<?xml version="1.0" encoding="utf-8"?>
<?xml-model href="rfc7991bis.rnc"?>
<!DOCTYPE rfc [
<!ENTITY nbsp "&#160;">
<!ENTITY zwsp "&#8203;">
<!ENTITY nbhy "&#8209;">
<!ENTITY wj "&#8288;">
]>
<rfc category="info" consensus="true"
     docName="draft-netana-netmod-yang-anydata-validation-00"
     ipr="trust200902" obsoletes="" sortRefs="true"
     submissionType="IETF" symRefs="true" tocInclude="true" updates=""
     version="3" xml:lang="en"
     xmlns:xi="http://www.w3.org/2001/XInclude"
     xmlns:ns2="http://www.w3.org/2000/svg"
     xmlns:ns="http://www.w3.org/1999/xlink">
  <front>
    <title abbrev="anydata validation">Validating anydata in YANG
    Library context</title>

    <author fullname="Ahmed Elhassany" initials="A" surname="Elhassany">
      <organization>Swisscom</organization>

      <address>
        <postal>
          <street>Binzring 17</street>

          <city>Zurich</city>

          <code>8045</code>

          <country>Switzerland</country>
        </postal>

        <phone/>

        <email>ahmed.elhassany@swisscom.com</email>

        <uri/>
      </address>
    </author>

    <author fullname="Thomas Graf" initials="T" surname="Graf">
      <organization>Swisscom</organization>

      <address>
        <postal>
          <street>Binzring 17</street>

          <city>Zurich</city>

          <code>8045</code>

          <country>Switzerland</country>
        </postal>

        <email>thomas.graf@swisscom.com</email>
      </address>
    </author>

    <date day="29" month="October" year="2026"/>

    <area>General</area>

    <workgroup>NETMOD</workgroup>

    <abstract>
      <t>The YANG "anydata" statement carries data whose data model is not
      known when the module is designed. This document defines the context
      that is needed to validate such content: the schema context, the
      "anydata" node, a schema anchor, and the datastore. It describes how
      this context is obtained for the uses of "anydata" in IETF YANG
      modules, how the schema node of each node in the content is found, and
      which YANG constraints are checked.</t>
    </abstract>
  </front>

  <middle>
    <section>
      <name>Introduction</name>

      <t><xref section="7.10" target="RFC7950"/> defines the "anydata"
      statement to represent an unknown set of nodes that can be modeled
      with YANG, but whose data model is not known at module design
      time. The same section notes that the data model for anydata
      content can become known through protocol signaling or other
      means and leaves those means out of scope nor requires them.</t>

      <t>Many IETF YANG modules use "anydata" (see <xref
      target="survey"/>), including <xref target="RFC8040"/>, <xref
      target="RFC8072"/>, <xref target="RFC8526"/>, <xref
      target="RFC8639"/>, <xref target="RFC8641"/>, <xref
      target="RFC9144"/>, and <xref target="RFC9195"/>. In most of these
      uses, the content is not arbitrary: the defining document states
      in prose that it is YANG instance data from a YANG datastore,
      instantiated from the same modules the producer implements. When a
      server receives such content as input, for example the value of a
      YANG Patch edit, it validates the content against its own schema
      and datastore as part of processing the operation. When anydata
      content is produced as output, however, for example in YANG-Push
      notifications or the reply to a datastore comparison, no such step
      exists on the receiving side. Current YANG implementations accept
      any well-formed, namespace-qualified content there and do not
      validate it against any YANG schema: not data types or ranges, and
      not "mandatory", "min-elements", "must", or "when" constraints.
      Even input is not always validated: YANG configuration templates
      <xref target="I-D.tt-netmod-yang-config-templates"/> store
      reusable configuration as anydata content in &lt;running&gt;, and
      because that content is opaque to the server, it cannot be
      validated when the template is defined, only once the template is
      expanded.</t>

      <t>That gap has become significant because anydata output is no
      longer consumed only by the client that requested it. For
      instance, network operators collect YANG-Push notifications from
      thousands of network nodes and forward them through message
      brokers into analytics pipelines <xref
      target="I-D.ietf-nmop-yang-message-broker-integration"/>. The
      components that consume this data are decoupled from the producer,
      have no protocol session through which to learn its schema, and
      process the data long after it was sent. For example, the
      "in-octets" counter of <xref target="RFC8343"/> is of type
      "yang:counter64". If a network node with a software defect sends a
      YANG-Push update with a negative value for this counter, a
      consumer that validates the anydata content against the producer's
      schema rejects the value as a type violation. A consumer that
      cannot validate accepts it, and an analytics component that sums
      interface counters across the network computes a wrong traffic
      volume, which can lead to inaccurate billing or capacity planning.
      Such errors are costly to trace back to their source once the data
      has left the collection layer.</t>

      <t>Validating anydata content requires four pieces of context,
      none of which can be derived from the content alone:</t>

      <ol>
        <li>The schema context: the set of YANG modules, revisions,
        features, and deviations from which the content was
        instantiated. A YANG Library instance <xref target="RFC8525"/>
        is one way to describe it, but a validator can obtain the schema
        context by other means that are outside the scope of this
        document.</li>

        <li>The anydata node: the schema node whose content is
        validated. A message can contain more than one anydata node, and
        each can carry differently scoped content.</li>

        <li>The schema anchor: the schema node at which the content is
        rooted. Anydata content is not always encoded from the top of
        the schema tree. The value of a YANG Patch <xref
        target="RFC8072"/> edit is encoded relative to the edit's
        target, and YANG-Push on-change updates <xref target="RFC8641"/>
        and datastore comparison results <xref target="RFC9144"/> both
        carry their data as YANG Patch edits. Configuration template
        content can likewise start at any level of the schema tree. A
        validator that assumes the top of the schema tree wrongly
        rejects such content.</li>

        <li>The datastore from which the content was taken. It
        determines which schema applies and which nodes may appear: the
        conventional configuration datastores contain only "config true"
        nodes, while &lt;operational&gt; also contains "config false"
        nodes (<xref section="5" target="RFC8342"/>). It also determines
        which constraints hold: constraints that hold in &lt;running&gt;
        or &lt;intended&gt; do not necessarily hold in
        &lt;operational&gt; (<xref section="5.3" target="RFC8342"/>).
        Anydata content, however, is often a fragment of that datastore
        rather than a complete copy of it, because a subscription
        filter, a YANG Patch edit, or a configuration template selects
        only part of the data tree. The consumer therefore chooses
        between two options, which follow the split in <xref
        section="8.1" target="RFC7950"/>. Under anydata-complete, the
        content, rooted at the schema anchor, is treated as a complete
        data tree, and all constraints are enforced. Under
        anydata-candidate, the content is treated like configuration in
        a candidate datastore that has not yet been committed: every
        node is still checked against its schema node, including data
        types, ranges, patterns, list keys, and choices, but none of the
        constraints that only a valid data tree satisfies ("must",
        "when", "unique", "mandatory", "min-elements", "max-elements",
        and references to other nodes) is enforced. The name refers to
        this uncommitted state; it does not mean validation against the
        &lt;candidate&gt; datastore. For example, content from a
        YANG-Push subscription to &lt;running&gt; whose filter excludes
        mandatory leaves fails anydata-complete by construction, but it
        can be validated with anydata-candidate.</li>
      </ol>

      <t>Existing mechanisms do not provide this context. <xref
      target="RFC8528">YANG Schema Mount</xref> mounts complete data
      models at a fixed point of the schema tree and cannot describe an
      arbitrary subset of an instantiated data tree, such as one
      selected by a YANG-Push subscription filter. YANG Full Embed <xref
      target="I-D.jouqui-netmod-yang-full-include"/> complements Schema
      Mount at module design time but has the same limitation. A
      design-time substatement of "anydata" could declare that the
      content of a node is expected to be valid YANG instance data, but
      it cannot carry the schema anchor or the datastore, because both
      are often known only at run time, for example when a YANG-Push
      subscription is established.</t>

      <t>This document therefore defines the validation context of an
      anydata node: the four inputs listed above, how each one is
      obtained for the uses of "anydata" surveyed in <xref
      target="survey"/>, how the schema node of each node in the content
      is found, and which constraints are checked under each option.
      Today, each implementation that validates anydata content defines
      its own way to receive this context. Other specifications that use
      "anydata" can state how their content is validated by referencing
      this document. How the validation context is conveyed to a
      validator is outside the scope of this document. This document
      does not change the "anydata" statement, does not constrain how
      YANG modules use "anydata", and does not require any existing
      client or server to perform validation.</t>

      <t>Validation remains optional and is a decision of the consumer.
      A consumer that detects non-conforming content can, for example,
      discard the message, log it for further analysis, or alert an
      operator, instead of passing incorrect data on to the systems that
      depend on it.</t>

      <section>
        <name>Requirements Language</name>

        <t>The key words "MUST", "MUST NOT", "REQUIRED", "SHALL", "SHALL
        NOT", "SHOULD", "SHOULD NOT", "RECOMMENDED", "NOT RECOMMENDED",
        "MAY", and "OPTIONAL" in this document are to be interpreted as
        described in BCP 14 <xref target="RFC2119"/> <xref
        target="RFC8174"/> when, and only when, they appear in all
        capitals, as shown here.</t>
      </section>
    </section>

    <section anchor="terminology">
      <name>Terminology</name>

      <t>This document uses the terms data node, data tree, instance
      identifier, schema node, and schema tree as defined in <xref
      target="RFC7950"/>; datastore, datastore schema, conventional
      configuration datastore, operational state datastore
      (&lt;operational&gt;), client, server, and notification as defined
      in <xref target="RFC8342"/>; and event record, event stream,
      publisher, and receiver as defined in <xref
      target="RFC8639"/>.</t>

      <t>The following terms are defined in this document:</t>

      <dl newline="false" spacing="normal">
        <dt>content:</dt>

        <dd>The value of one instance of an "anydata" node, that is, the
        data nodes encoded as its children, with their descendants
        ("anydata content" in <xref section="7.10"
        target="RFC7950"/>).</dd>

        <dt>first-level node:</dt>

        <dd>A node of the content that is a direct child of the
        "anydata" node in the encoded message.</dd>

        <dt>fragment:</dt>

        <dd>Content that is part of a data tree but leaves out nodes of
        that data tree, for example, because a selection filter, an edit,
        or a configuration template selects only part of it.</dd>

        <dt>schema context:</dt>

        <dd>The set of YANG modules, with their revisions, supported
        features, and deviations, and whether each module is implemented
        or import-only, from which the content was instantiated. For
        content taken from a datastore, it is the set of modules that
        defines the datastore schema of that datastore. The
        content-schema of a YANG instance data set (<xref
        target="RFC9195"/>) is a schema context.</dd>

        <dt>schema anchor:</dt>

        <dd>The schema node whose children are the first-level nodes of
        the content (<xref target="schema-anchor"/>). It is the root of
        the schema tree, written "/", when the content is encoded from
        the top of the data tree.</dd>

        <dt>validation context:</dt>

        <dd>The inputs needed to validate one instance of an "anydata"
        node: the schema context, the "anydata" node, the schema anchor,
        and the datastore.</dd>

        <dt>producer:</dt>

        <dd>The entity that encodes the content, for example a server or
        a publisher.</dd>

        <dt>consumer:</dt>

        <dd>An entity that receives the content, for example a client or
        a receiver, and decides whether it is validated, and with which
        option.</dd>

        <dt>validator:</dt>

        <dd>An implementation that validates content as defined in this
        document.</dd>

        <dt>anydata-complete, anydata-candidate:</dt>

        <dd>The two validation options defined in <xref
        target="validation-options"/>.</dd>
      </dl>
    </section>

    <section anchor="survey">
      <name>Survey of existing use of "anydata"</name>

      <t>This section lists the "anydata" nodes defined in published
      IETF YANG modules and in active Internet-Drafts at the time of
      writing. For each use it records four facts that a validator needs
      and that the defining document either states or leaves open:</t>

      <dl newline="false" spacing="normal">
        <dt>Schema context:</dt>

        <dd>where the set of YANG modules that describe the content
        comes from.</dd>

        <dt>Anchor:</dt>

        <dd>the schema node that the top-level nodes of the content are
        children of. The anchor is the datastore root only for some
        uses; others encode content relative to a path carried next to
        the "anydata" node.</dd>

        <dt>Datastore:</dt>

        <dd>the datastore whose schema and validation rules apply, if
        any.</dd>

        <dt>Fragment:</dt>

        <dd>whether the content can be a part of a data tree, for
        example because a selection filter or an edit leaves out nodes,
        including mandatory ones, that the full data tree contains.
        "may" means the content is a fragment when a filter is applied
        or when the defining document allows partial data.</dd>
      </dl>

      <t><xref target="survey-table"/> lists the anchor, the datastore
      and whether the content is a fragment for each use. The
      subsections that follow group the uses by purpose and describe
      their schema context.</t>

      <table anchor="survey-table">
        <name>"anydata" nodes in IETF YANG modules</name>

        <thead>
          <tr>
            <th>Document</th>

            <th>"anydata" node</th>

            <th>Anchor</th>

            <th>Datastore</th>

            <th>Fragment</th>
          </tr>
        </thead>

        <tbody>
          <tr>
            <td><xref format="none" target="RFC8526">RFC
            8526</xref></td>

            <td>get-data input subtree-filter</td>

            <td>root</td>

            <td>"datastore" input leaf</td>

            <td>yes</td>
          </tr>

          <tr>
            <td><xref format="none" target="RFC8526">RFC
            8526</xref></td>

            <td>get-data output data</td>

            <td>root</td>

            <td>"datastore" input leaf</td>

            <td>may</td>
          </tr>

          <tr>
            <td><xref format="none" target="RFC8526">RFC
            8526</xref></td>

            <td>edit-data input config</td>

            <td>root</td>

            <td>"datastore" input leaf (configuration datastore)</td>

            <td>yes</td>
          </tr>

          <tr>
            <td><xref format="none" target="RFC8072">RFC
            8072</xref></td>

            <td>yang-patch edit value</td>

            <td>content relative to edit "target"</td>

            <td>datastore of the PATCH target resource</td>

            <td>yes</td>
          </tr>

          <tr>
            <td><xref format="none" target="RFC9144">RFC
            9144</xref></td>

            <td>compare input subtree-filter</td>

            <td>root</td>

            <td>"source" and "target" input leaves</td>

            <td>yes</td>
          </tr>

          <tr>
            <td><xref format="none" target="RFC9144">RFC
            9144</xref></td>

            <td>compare output edit value and source-value</td>

            <td>content relative to edit "target"</td>

            <td>"target" and "source" datastores respectively</td>

            <td>yes</td>
          </tr>

          <tr>
            <td><xref format="none" target="RFC8639">RFC
            8639</xref></td>

            <td>stream-subtree-filter</td>

            <td>"/" (first-level node is a notification)</td>

            <td>none (event stream)</td>

            <td>yes</td>
          </tr>

          <tr>
            <td><xref format="none" target="RFC8641">RFC
            8641</xref></td>

            <td>datastore-subtree-filter</td>

            <td>root</td>

            <td>subscription's target datastore</td>

            <td>yes</td>
          </tr>

          <tr>
            <td><xref format="none" target="RFC8641">RFC
            8641</xref></td>

            <td>push-update datastore-contents</td>

            <td>root</td>

            <td>subscription's target datastore</td>

            <td>may</td>
          </tr>

          <tr>
            <td><xref format="none" target="RFC8641">RFC
            8641</xref></td>

            <td>push-change-update yang-patch edit value</td>

            <td>content relative to edit "target"</td>

            <td>subscription's target datastore</td>

            <td>yes</td>
          </tr>

          <tr>
            <td><xref format="none" target="RFC9195">RFC
            9195</xref></td>

            <td>content-data</td>

            <td>root</td>

            <td>not specified</td>

            <td>may</td>
          </tr>

          <tr>
            <td><xref format="none" target="RFC9195">RFC
            9195</xref></td>

            <td>inline-yang-library</td>

            <td>root</td>

            <td>none (fixed schema: ietf-yang-library)</td>

            <td>no</td>
          </tr>

          <tr>
            <td><xref format="none" target="RFC8040">RFC
            8040</xref></td>

            <td>errors error error-info</td>

            <td>not specified</td>

            <td>none</td>

            <td>unknown</td>
          </tr>

          <tr>
            <td><xref format="none" target="RFC8532">RFC
            8532</xref></td>

            <td>test point root (schema mount point)</td>

            <td>root of the mounted schema</td>

            <td>as for the parent data tree</td>

            <td>no</td>
          </tr>

          <tr>
            <td><xref format="none"
            target="I-D.tt-netmod-yang-config-templates">YANG
            Templates</xref></td>

            <td>template content</td>

            <td>"data-path" leaf (any level)</td>

            <td>&lt;running&gt;, or &lt;system&gt;</td>

            <td>yes</td>
          </tr>

          <tr>
            <td><xref format="none"
            target="I-D.ietf-netconf-notif-envelope">Notif.
            Envelope</xref></td>

            <td>envelope contents</td>

            <td>"/" (first-level node is a notification)</td>

            <td>none (event stream)</td>

            <td>no</td>
          </tr>

          <tr>
            <td><xref format="none"
            target="I-D.ietf-netconf-yang-push-2">YANG-Push
            2</xref></td>

            <td>filter subtree</td>

            <td>root</td>

            <td>subscription's target datastore</td>

            <td>yes</td>
          </tr>

          <tr>
            <td><xref format="none"
            target="I-D.ietf-netconf-yang-push-2">YANG-Push
            2</xref></td>

            <td>update merge and replaced-by</td>

            <td>content relative to "path-prefix" plus
            "target-path"</td>

            <td>subscription's target datastore</td>

            <td>yes</td>
          </tr>

          <tr>
            <td><xref format="none"
            target="I-D.ietf-nmop-message-broker-telemetry-message">Telemetry
            Message</xref></td>

            <td>message payload</td>

            <td>"/" (first-level node is a YANG-Push notification)</td>

            <td>none; nested "datastore-contents" uses the
            subscription's target datastore</td>

            <td>may</td>
          </tr>

          <tr>
            <td><xref format="none"
            target="I-D.ietf-nmop-message-broker-telemetry-message">Telemetry
            Message</xref></td>

            <td>label anydata-values</td>

            <td>not specified</td>

            <td>none</td>

            <td>unknown</td>
          </tr>

          <tr>
            <td><xref format="none"
            target="I-D.ietf-nmop-message-broker-telemetry-message">Telemetry
            Message</xref></td>

            <td>subscription subtree-filter</td>

            <td>"/" (first-level node is a data node or a
            notification)</td>

            <td>as for the subscription</td>

            <td>yes</td>
          </tr>
        </tbody>
      </table>

      <section anchor="survey-filters">
        <name>Selection filters</name>

        <t>Subtree filters (<xref section="6" target="RFC6241"/>) are
        carried in "anydata" by <xref target="RFC8526"/>, <xref
        target="RFC9144"/>, <xref target="RFC8641"/> and <xref
        target="I-D.ietf-netconf-yang-push-2"/>, where they select a
        subtree of a datastore, and by <xref target="RFC8639"/>, where
        they select event records from an event stream. In the datastore
        case the anchor is the datastore root of the datastore named by
        the operation or the subscription. In the event stream case the
        top-level node is a notification, whose schema is defined by a
        "notification" statement in the publisher's YANG Library; the
        content is therefore not undefined YANG-like data.</t>

        <t>A subtree filter is a pattern, not instance data: selection
        nodes are empty, containment nodes may omit list keys, and
        mandatory nodes are usually absent. Only the node names, and the
        values of content match nodes, can be checked against the
        schema.</t>
      </section>

      <section anchor="survey-retrieved">
        <name>Retrieved datastore content</name>

        <t>The "data" output of get-data <xref target="RFC8526"/> and
        the "datastore-contents" of push-update <xref target="RFC8641"/>
        carry the part of a datastore that matched a selection filter,
        anchored at the datastore root. The schema and the validation
        rules are those of the selected datastore: content from
        &lt;operational&gt; includes "config false" nodes and may carry
        origin metadata <xref target="RFC7952"/>, and it need not
        satisfy constraints that apply only to configuration datastores
        (<xref section="5.3" target="RFC8342"/>).</t>
      </section>

      <section anchor="survey-edits">
        <name>Edits and differences</name>

        <t>The edit-data operation <xref target="RFC8526"/> carries
        configuration anchored at the datastore root, together with
        operation metadata, and the server validates the result.</t>

        <t>YANG Patch <xref target="RFC8072"/> carries the new content
        of each edit in the "value" node. The top-level node of "value"
        is an instance of the data node identified by the "target" leaf.
        "target" is an absolute path when the PATCH request targets the
        datastore resource and a path relative to the target resource
        otherwise (<xref section="2.4" target="RFC8072"/>). The anchor
        is therefore the parent of the target data node, and it is only
        known after "target" is resolved. The anchor is kept as an
        instance path with its list key values: the schema node is found
        by ignoring the keys, and the keys identify the ancestor
        instances of the content, so that references from the content to
        its ancestors can be evaluated.</t>

        <t>The YANG Patch structure is reused by push-change-update
        <xref target="RFC8641"/> to report on-change updates of the
        subscription's target datastore, and by the compare operation
        <xref target="RFC9144"/> to report differences. RFC 8641 and RFC
        9144 do not state the base of "target"; their examples use
        absolute paths. In RFC 9144, one edit carries content from two
        datastores: "value" from the target datastore and
        "source-value", an augmentation, from the source datastore. The
        two nodes of the same edit can therefore be subject to different
        datastore rules, for example &lt;intended&gt; and
        &lt;operational&gt;.</t>

        <t>The update notification of <xref
        target="I-D.ietf-netconf-yang-push-2"/> carries "merge" and
        "replaced-by" content relative to the path formed by a common
        "path-prefix" and a per-update "target-path".</t>
      </section>

      <section anchor="survey-stored">
        <name>Stored instance data and templates</name>

        <t>YANG Instance Data <xref target="RFC9195"/> stores a data
        tree in "content-data", anchored at the root, and states that
        the data MUST conform to the YANG modules given in
        "content-schema". The schema context is given as a list of
        modules, as an inline YANG Library in the "inline-yang-library"
        node, or as a reference to another instance data file. RFC 9195
        thus already describes the schema of "anydata" content with YANG
        Library. The "inline-yang-library" node is itself "anydata"
        whose schema is fixed by its description (ietf-yang-library
        revision 2019-01-04).</t>

        <t>YANG Configuration Templates <xref
        target="I-D.tt-netmod-yang-config-templates"/> store template
        content as "anydata" in &lt;running&gt;, or in &lt;system&gt;
        where supported. A "data-path" leaf anchors the content at any
        location of the schema tree, defaulting to the root. Servers
        SHOULD validate a template when it is defined and MUST validate
        it when it is applied, but a template need not contain mandatory
        nodes, so definition-time validation cannot apply all
        constraints.</t>
      </section>

      <section anchor="survey-messages">
        <name>Message payloads</name>

        <t>The notification envelope <xref
        target="I-D.ietf-netconf-notif-envelope"/> carries the content
        of a notification in the "contents" node of a YANG structure
        <xref target="RFC8791"/>. The name and namespace of the
        top-level node are those of the module that defines the
        notification, so the content can be validated against the
        publisher's YANG Library; it is not datastore content.</t>

        <t>The telemetry message <xref
        target="I-D.ietf-nmop-message-broker-telemetry-message"/>
        carries the message received from a network element in the
        "payload" node. The payload is a YANG-Push notification <xref
        target="RFC8641"/>, so its first-level node is that
        notification, under the root "/". The "datastore-contents"
        inside the notification is a nested "anydata" node with its own
        validation context: its anchor is again "/", and its datastore
        is the subscription's target datastore. The subscription
        metadata identifies that datastore and the filter, and can
        identify the publisher's YANG Library through
        "yang-library-content-id". Unlike most uses, the message thus
        carries the schema context and the datastore together with the
        content. Operator labels may also carry "anydata" values whose
        schema is not defined.</t>
      </section>

      <section anchor="survey-unspecified">
        <name>Content without a defined schema</name>

        <t>RESTCONF <xref target="RFC8040"/> uses "error-info" to convey
        additional error information as a container of data nodes.
        Neither the anchor nor the schema of that information is defined
        by RESTCONF or signaled in the response.</t>
      </section>

      <section anchor="survey-mount">
        <name>Schema mount on an "anydata" node</name>

        <t>The connectionless OAM model <xref target="RFC8532"/> defines
        an "anydata" node named "root" with the "mount-point" extension
        of <xref target="RFC8528"/>, so that technology-specific modules
        can be mounted under each test point. The mounted schema is
        described by the schema mount data, which includes YANG library
        data for the mount point (<xref section="3.3"
        target="RFC8528"/>). The content is validated against that
        mounted schema, with the root of the mounted schema as the
        anchor. <xref section="3.1" target="RFC8528"/> allows
        "mount-point" only as a substatement of "container" and
        "list".</t>
      </section>

      <section anchor="survey-related">
        <name>Related constructs that do not use "anydata"</name>

        <ul>
          <li>NETCONF <xref target="RFC6241"/> and NETCONF Monitoring
          <xref target="RFC6022"/> use "anyxml" for filters, retrieved
          data and edit content. RFC 8526 replaces these uses with
          "anydata" for NMDA datastores. This document does not change
          "anyxml".</li>

          <li>YANG Schema Mount <xref target="RFC8528"/> and YANG
          Library <xref target="RFC8525"/> define no "anydata"
          nodes.</li>

          <li>A YANG structure <xref target="RFC8791"/> is encoded in
          the same way as an "anydata" node, but its schema is defined
          by the "structure" statement.</li>

          <li>The list pagination extensions to NETCONF augment get-data
          <xref target="RFC8526"/> with input parameters and add no
          "anydata" nodes.</li>
        </ul>
      </section>

      <section anchor="survey-summary">
        <name>Observations</name>

        <ul>
          <li>Most uses carry content that a YANG Library can describe.
          Only RESTCONF "error-info" and the telemetry message labels
          leave the schema undefined.</li>

          <li>The anchor is not always the root. YANG Patch, its reuse
          in RFC 8641 and RFC 9144, YANG-Push version 2 and
          configuration templates encode content relative to a path
          carried next to the "anydata" node. For notification payloads
          the anchor is the root "/", and the first-level node is the
          notification itself.</li>

          <li>The applicable validation rules depend on the datastore,
          and one message can carry content from two datastores (RFC
          9144).</li>

          <li>Most uses carry fragments: filters, filtered retrievals,
          edits, differences and templates leave out nodes of the full
          data tree. A fragment taken from a configuration datastore,
          such as a YANG-Push subscription to &lt;running&gt; whose
          filter excludes mandatory leaves, cannot satisfy the
          constraints that need complete data. The validation rules stay
          those of the datastore, and the consumer chooses whether to
          apply complete or candidate validation to a given "anydata"
          node.</li>
        </ul>
      </section>
    </section>

    <section anchor="schema-lookup">
      <name>Instantiated data node schema lookup</name>

      <t>To validate "anydata" content, a validator first has to find,
      for each instantiated data node in the content, the schema node it
      is an instance of. This section defines that lookup. It uses the
      four inputs of the validation context: the schema context, the
      "anydata" node, the schema anchor, and the datastore.</t>

      <t>Below the first level of the content, no new rule is needed.
      Each encoding already identifies a child node relative to its
      parent (<xref section="7" target="RFC7950"/>, <xref section="4"
      target="RFC7951"/>, <xref section="3" target="RFC9254"/>). What
      the encodings do not define is the parent of the first-level
      nodes. This document uses the schema anchor as that parent.</t>

      <section anchor="schema-anchor">
        <name>Schema Anchor</name>

        <t>When the content is encoded from the top of the data tree,
        the schema anchor is the root of the schema tree, written "/".
        Otherwise, the anchor is a container, a list, a notification, or
        the input or output of an RPC or action.</t>

        <t>The anchor is represented as a node-instance-identifier
        (<xref target="RFC8341"/>): an instance-identifier in which key
        predicates are optional. The validator removes the key
        predicates and resolves the remaining path to a schema node.
        Choice and case nodes do not appear in the path, as in any
        instance-identifier. When the key predicates are present, the
        validator can also instantiate the ancestors of the content,
        including their list keys. This allows "must", "when", and
        leafref expressions in the content that refer to ancestor nodes
        to be evaluated. When they are absent, the ancestors cannot be
        instantiated: which list entry the content belongs to is
        unknown, so a reference that leaves the content through an
        ancestor cannot be resolved. Such references are treated as
        references to nodes outside the content (see <xref
        target="validation"/>). The lookup itself does not need the key
        predicates.</t>

        <t>The anchor changes where the first-level nodes are looked up.
        It does not change the root of the data tree. Absolute paths
        that appear in the content or in its schema, such as leafref
        "path" statements, "must" and "when" expressions, and
        instance-identifier values, are evaluated from the root of the
        data tree, as defined in <xref section="6.4.1"
        target="RFC7950"/>. In this respect the anchor differs from a
        schema mount point, under which paths are interpreted with the
        mount point as the root node (<xref section="4"
        target="RFC8528"/>).</t>

        <t>Defining documents identify the anchor in one of two
        ways:</t>

        <dl newline="false" spacing="normal">
          <dt>Target:</dt>

          <dd><t>A path carried with the content identifies the instance
          that the content is, for example the "target" of a YANG Patch
          edit <xref target="RFC8072"/>. The first-level node of the
          content is an instance of the schema node identified by the
          path, and the anchor is the parent of that schema node. A path
          of "/" is handled as defined by the document that carries
          it.</t> <t>The "target" of <xref target="RFC8072"/>, which
          <xref target="RFC8641"/> and <xref target="RFC9144"/> reuse,
          is not an instance-identifier. Its type,
          "target-resource-offset", is encoded as a data resource
          identifier of a RESTCONF request URI (<xref section="3.5.3"
          target="RFC8040"/>), for example "/song=Dear%20Rosemary". The
          validator converts such a path to the JSON encoding of an
          instance-identifier (<xref section="6.11" target="RFC7951"/>),
          which uses the same rule for module names: each
          "list=key1,key2" step becomes the list name followed by one
          key predicate per key, in the order of the list's "key"
          statement, and each key value is percent-decoded. When the
          target is relative to the target resource (<xref section="2.4"
          target="RFC8072"/>), the path of the target resource is
          converted in the same way and prepended.</t></dd>

          <dt>Location:</dt>

          <dd>A path carried with the content identifies the location
          under which the content is placed, for example the "data-path"
          of a configuration template <xref
          target="I-D.tt-netmod-yang-config-templates"/>. The
          first-level nodes of the content are children of the schema
          node identified by the path, and the anchor is that schema
          node.</dd>
        </dl>

        <t>In both cases, the anchor is a property of an instance of the
        "anydata" node, not of the "anydata" schema node. For example,
        each edit of a YANG Patch carries its own "target", and
        therefore the "value" of each edit has its own anchor.</t>

        <t>At the root anchor, a first-level node is either a top-level
        data node or a top-level notification. When the validation
        context names a datastore, the first-level nodes MUST be data
        nodes. When the content is an event record from an event stream,
        as in <xref target="RFC8639"/> and <xref
        target="I-D.ietf-netconf-notif-envelope"/>, the first-level node
        MUST be a notification.</t>
      </section>

      <section anchor="lookup-procedure">
        <name>Lookup Procedure</name>

        <t>A validator performs the lookup for one instance of an
        "anydata" node as follows:</t>

        <ol spacing="normal">
          <li>Resolve the anchor in the schema context. If the anchor
          cannot be resolved, or resolves to a node that cannot have
          children, the content is not validated (see <xref
          target="lookup-outcomes"/>).</li>

          <li>For each first-level node, determine its module from the
          encoding, as defined in <xref
          target="first-level-encoding"/>.</li>

          <li>Find the schema node with that module and identifier among
          the schema children of the anchor, looking through choice and
          case nodes and including nodes added by "augment" statements.
          A schema node is eligible only if the module that defines it
          is implemented in the schema context (<xref section="5.6.5"
          target="RFC7950"/>), its "if-feature" statements are
          satisfied, and no deviation in the schema context removes
          it.</li>

          <li>Look up the descendants of each first-level node with the
          rules of the encoding, without change. When the lookup reaches
          an "anydata", "anyxml", or schema mount point node, continue
          as defined in <xref target="nested-content"/>.</li>
        </ol>
      </section>

      <section anchor="first-level-encoding">
        <name>Encoding Rules for the First Level</name>

        <section>
          <name>XML</name>

          <t>The XML encoding needs no additional rule. The value of an
          "anydata" node is a set of nodes encoded as subelements of the
          "anydata" element (<xref section="7.10.2" target="RFC7950"/>),
          and the namespace of each subelement is the XML namespace of
          the module that defines the node. The namespace of every
          element is resolved by the XML namespace rules, including
          declarations inherited from ancestor elements. A first-level
          element without its own namespace declaration therefore
          inherits the default namespace in scope at the "anydata"
          element, which is usually the namespace of the module that
          defines the "anydata" node.</t>

          <t>The namespace declarations in scope at the "anydata"
          element also apply to prefixes used in values of the content,
          such as identityref and instance-identifier values (<xref
          section="9.10.3" target="RFC7950"/>, <xref section="9.13.2"
          target="RFC7950"/>). A validator that extracts the content
          from the message MUST preserve these declarations.</t>
        </section>

        <section>
          <name>JSON</name>

          <t>A member name is either namespace-qualified or simple, and
          a simple name belongs to the module of its parent node (<xref
          section="4" target="RFC7951"/>). The content of an "anydata"
          node follows the same rules (<xref section="5.5"
          target="RFC7951"/>). For the first-level members, the anchor
          takes the role of the parent node. This matches the YANG Patch
          examples, where an edit whose target is a list entry of the
          target resource carries the list with a simple member name
          (<xref section="A.1.2" target="RFC8072"/>), and an edit whose
          target is in the datastore carries a namespace-qualified name
          (<xref section="A.1.5" target="RFC8072"/>). Therefore:</t>

          <ul spacing="normal">
            <li>A first-level member name MUST be namespace-qualified
            when the anchor is the root or when the module of the node
            differs from the module of the anchor. Otherwise, the simple
            form is used.</li>

            <li>A validator resolves a simple first-level member name in
            the module of the anchor. A simple first-level member name
            at the root anchor is an error.</li>

            <li>A validator SHOULD also accept a namespace-qualified
            first-level member name whose module is the module of the
            anchor, because a producer may have qualified it relative to
            the "anydata" node.</li>
          </ul>
        </section>

        <section>
          <name>CBOR</name>

          <t>When the content of an "anydata" node (<xref section="4.5"
          target="RFC9254"/>) uses names as map keys, the rules for JSON
          above apply, as <xref section="3.3" target="RFC9254"/> uses
          the same qualification rule as JSON.</t>

          <t>When the content uses YANG Schema Item iDentifiers (SIDs)
          <xref target="RFC9595"/> as map keys, the reference SID of the
          first-level map is determined by <xref section="3.2"
          target="RFC9254"/>: it is the SID of the "anydata" node, or
          zero if the "anydata" node is encoded with a name as its key.
          A first-level key can also be an absolute SID (tag 47).
          Because a SID identifies a schema node independently of its
          position, the anchor is not needed to identify the node. The
          validator MUST check that the identified schema node is a
          child of the anchor. When SIDs are used, the schema context
          includes the SID assignments of its modules.</t>
        </section>
      </section>

      <section anchor="anchor-per-use">
        <name>Anchor of the Surveyed Uses</name>

        <t>For each use of "anydata" listed in <xref target="survey"/>,
        the anchor is obtained as follows.</t>

        <table>
          <name>Anchor of the surveyed "anydata" uses</name>

          <thead>
            <tr>
              <th>Use</th>

              <th>Anchor</th>

              <th>Way</th>
            </tr>
          </thead>

          <tbody>
            <tr>
              <td>get-data output "data" and edit-data input "config"
              <xref target="RFC8526"/>; "content-data" <xref
              target="RFC9195"/>; push-update "datastore-contents" <xref
              target="RFC8641"/></td>

              <td>"/"</td>

              <td>fixed</td>
            </tr>

            <tr>
              <td>YANG Patch edit "value" <xref target="RFC8072"/></td>

              <td>the edit's "target", relative to the target resource
              unless the target resource is the datastore (<xref
              section="2.4" target="RFC8072"/>)</td>

              <td>Target</td>
            </tr>

            <tr>
              <td>push-change-update edit "value" <xref
              target="RFC8641"/></td>

              <td>the edit's "target"</td>

              <td>Target</td>
            </tr>

            <tr>
              <td>compare output edit "value" and "source-value" <xref
              target="RFC9144"/></td>

              <td>the edit's "target"</td>

              <td>Target</td>
            </tr>

            <tr>
              <td>update "merge" and "replaced-by" <xref
              target="I-D.ietf-netconf-yang-push-2"/></td>

              <td>"path-prefix" followed by "target-path"</td>

              <td>Target</td>
            </tr>

            <tr>
              <td>template "content" <xref
              target="I-D.tt-netmod-yang-config-templates"/></td>

              <td>"data-path"</td>

              <td>Location</td>
            </tr>

            <tr>
              <td>envelope "contents" <xref
              target="I-D.ietf-netconf-notif-envelope"/>; telemetry
              message "payload" <xref
              target="I-D.ietf-nmop-message-broker-telemetry-message"/></td>

              <td>"/" (a notification)</td>

              <td>fixed</td>
            </tr>

            <tr>
              <td>subtree filters: get-data <xref target="RFC8526"/>,
              compare <xref target="RFC9144"/>,
              "datastore-subtree-filter" <xref target="RFC8641"/>,
              filter "subtree" <xref
              target="I-D.ietf-netconf-yang-push-2"/>, subscription
              "subtree-filter" <xref
              target="I-D.ietf-nmop-message-broker-telemetry-message"/></td>

              <td>"/"</td>

              <td>fixed</td>
            </tr>

            <tr>
              <td>"stream-subtree-filter" <xref target="RFC8639"/></td>

              <td>"/" (a notification)</td>

              <td>fixed</td>
            </tr>

            <tr>
              <td>"inline-yang-library" <xref target="RFC9195"/></td>

              <td>"/", with ietf-yang-library revision 2019-01-04 as the
              schema context</td>

              <td>fixed</td>
            </tr>

            <tr>
              <td>test point "root" <xref target="RFC8532"/></td>

              <td>root of the mounted schema; the schema context is the
              mounted YANG library data (<xref section="3.3"
              target="RFC8528"/>)</td>

              <td>fixed</td>
            </tr>

            <tr>
              <td>"error-info" <xref target="RFC8040"/>; label
              "anydata-values" <xref
              target="I-D.ietf-nmop-message-broker-telemetry-message"/></td>

              <td>not defined</td>

              <td>none</td>
            </tr>
          </tbody>
        </table>

        <t>A subtree filter is a pattern, not instance data (<xref
        section="6" target="RFC6241"/>): its nodes are looked up as
        defined here, but only node names and the values of content
        match nodes can be checked. Where the defining document gives no
        anchor and no schema, as for "error-info" and the telemetry
        message labels, the content is not validated.</t>

        <t>Neither <xref target="RFC8641"/> nor <xref target="RFC9144"/>
        states what the "target" of an edit is relative to; their
        examples use absolute paths, and this document assumes absolute
        paths for both. In <xref target="RFC9144"/>, "value" and
        "source-value" of the same edit share the anchor but come from
        different datastores, so each is validated with its own
        validation context.</t>

        <t>A selection filter does not change the anchor. A subtree
        filter can select several subtrees of a datastore (<xref
        section="3.6" target="RFC8641"/>), and an XPath filter can
        select any node set, but the selected data is still encoded from
        the root of the data tree. One root anchor therefore covers all
        selected subtrees, and the nodes that the filter left out are
        handled by the option chosen in <xref target="validation"/>.
        None of the surveyed uses encodes, in one instance of an
        "anydata" node, first-level nodes that are children of different
        schema nodes, so a single anchor per instance is sufficient.</t>
      </section>

      <section anchor="nested-content">
        <name>Nested "anydata", "anyxml", and Schema Mount Points</name>

        <dl newline="true" spacing="normal">
          <dt>anyxml:</dt>

          <dd>The content of an "anydata" node consists of nodes that
          can be modeled with YANG, except anyxml (<xref section="7.10"
          target="RFC7950"/>). An instance of an "anyxml" node in the
          content is an error.</dd>

          <dt>Nested "anydata":</dt>

          <dd>The content of an "anydata" node inside the content is
          validated only if the validator has a validation context for
          that "anydata" node, with its own anchor and datastore.
          Otherwise, its content is not validated, and the validator
          reports it as such. For example, the "payload" of a telemetry
          message <xref
          target="I-D.ietf-nmop-message-broker-telemetry-message"/> is a
          YANG-Push notification whose "datastore-contents" is itself an
          "anydata" node with a different datastore.</dd>

          <dt>Schema mount points:</dt>

          <dd>Below a schema mount point <xref target="RFC8528"/>, the
          lookup continues in the mounted schema, which is identified by
          the schema mount data and the YANG library data of that mount
          point (<xref section="3.3" target="RFC8528"/>). When the
          content is a fragment, that data is usually not part of the
          content, so the schema context has to include it. If the
          mounted schema is not available, the content below the mount
          point is not validated.</dd>
        </dl>

        <t>Metadata annotations <xref target="RFC7952"/> attached to
        nodes in the content, such as the "origin" annotation of
        &lt;operational&gt;, are resolved in the schema context like any
        other annotation. This document defines no new annotations.
        The validation context applies to the whole content of one
        "anydata" instance and is known when the content is produced;
        it is not a property of individual nodes. The uses surveyed in
        <xref target="survey"/> already carries the anchor and the
        datastore next to the "anydata" node, in the YANG Patch target,
        the template data-path, or the subscription, so an annotation
        would duplicate them. An annotation remains possible for a use
        that carries neither, and this document does not preclude
        one.</t>
      </section>

      <section anchor="lookup-outcomes">
        <name>Lookup Outcomes</name>

        <t>The lookup of one instance of an "anydata" node ends in one
        of three outcomes:</t>

        <dl newline="false" spacing="normal">
          <dt>Found:</dt>

          <dd>Every node in the content has a schema node. Validation
          continues as defined in <xref target="validation"/>.</dd>

          <dt>Invalid:</dt>

          <dd>At least one node in the content has no schema node, or is
          placed where its schema node is not allowed.</dd>

          <dt>Not validated:</dt>

          <dd>The validator lacks the context to perform the lookup, for
          all of the content or for a subtree of it. This is not
          evidence that the content is wrong.</dd>
        </dl>

        <t>A validator reports errors with the "error-tag" values of
        <xref section="A" target="RFC6241"/>, as listed in <xref
        target="lookup-errors"/>.</t>

        <table anchor="lookup-errors">
          <name>Lookup failures</name>

          <thead>
            <tr>
              <th>Case</th>

              <th>Outcome</th>

              <th>error-tag</th>
            </tr>
          </thead>

          <tbody>
            <tr>
              <td>The namespace or module name of a node is not in the
              schema context</td>

              <td>invalid</td>

              <td>unknown-namespace</td>
            </tr>

            <tr>
              <td>The module is in the schema context but not
              implemented, or the node is removed by a feature or
              deviation</td>

              <td>invalid</td>

              <td>unknown-element</td>
            </tr>

            <tr>
              <td>The schema node exists, but not as a child of the
              anchor or of the parent node</td>

              <td>invalid</td>

              <td>unknown-element</td>
            </tr>

            <tr>
              <td>A JSON or CBOR member name is not a valid name, or is
              simple at the root anchor</td>

              <td>invalid</td>

              <td>bad-element</td>
            </tr>

            <tr>
              <td>An instance of an "anyxml" node</td>

              <td>invalid</td>

              <td>bad-element</td>
            </tr>

            <tr>
              <td>The anchor cannot be resolved</td>

              <td>not validated</td>

              <td>none</td>
            </tr>

            <tr>
              <td>Nested "anydata" without a validation context, or a
              mounted schema that is not available</td>

              <td>not validated (subtree)</td>

              <td>none</td>
            </tr>
          </tbody>
        </table>
      </section>
    </section>

    <section anchor="validation">
      <name>Validating "anydata" Content</name>

      <t>This section defines how a validator checks "anydata" content
      once the schema lookup of <xref target="schema-lookup"/> has found
      a schema node for every node in it. It does not define new
      constraints. It selects which of the constraints of <xref
      section="8.1" target="RFC7950"/> are checked, using two options:
      anydata-complete and anydata-candidate. The consumer chooses the
      option for each instance of an "anydata" node; this document does
      not define a default.</t>

      <section anchor="validation-options">
        <name>The anydata-complete and anydata-candidate Options</name>

        <t><xref section="8.1" target="RFC7950"/> separates the
        properties that are true in all data trees from the properties
        that are true in a valid data tree. A configuration datastore
        that is not yet committed, such as &lt;candidate&gt;, satisfies
        the first set at all times and the second set only when it is
        validated (<xref section="8.3.3" target="RFC7950"/>). The two
        options follow this split.</t>

        <dl newline="true">
          <dt>anydata-candidate:</dt>

          <dd><t>The validator checks every node of the content against
          its schema node:</t> <ul>
              <li>All leaf and leaf-list values match the type of their
              schema node, including "range", "length", and "pattern"
              restrictions. The value of a leafref matches the type of
              the leaf it refers to, but the referenced instance is not
              required to exist.</li>

              <li>All key leafs are present for all list entries.</li>

              <li>Nodes are present for at most one case branch of each
              choice.</li>

              <li>No node is present whose "if-feature" expression
              evaluates to "false" in the schema context.</li>

              <li>No "config false" node is present when the datastore
              is a conventional configuration datastore (<xref
              section="5" target="RFC8342"/>).</li>
            </ul> <t>"must", "when", "unique", "mandatory",
          "min-elements", and "max-elements" statements are not checked,
          and leafref and instance-identifier references are not
          required to resolve. Evaluating "when" can require nodes that
          are not part of the content, so it is not checked under this
          option even though <xref section="8.1" target="RFC7950"/>
          lists it among the properties of all data trees.</t></dd>

          <dt>anydata-complete:</dt>

          <dd><t>The validator performs all checks of anydata-candidate
          and, in addition, checks every property that <xref
          section="8.1" target="RFC7950"/> requires of a valid data
          tree: "when", "must", "unique", "mandatory", "min-elements",
          and "max-elements", and the referential integrity of leafref
          and instance-identifier values whose "require-instance" is
          "true".</t> <t>The content is treated as self-contained.
          Expressions and references are evaluated on a data tree that
          consists of the ancestors instantiated from the schema anchor
          (<xref target="schema-anchor"/>) and the content. A reference
          to a node that is not in this data tree is not
          satisfied.</t></dd>
        </dl>

        <t>The anydata-complete option is intended for content that is
        complete for its schema anchor, such as the full reply to a
        get-data operation <xref target="RFC8526"/> on &lt;running&gt;
        or a YANG instance data file <xref target="RFC9195"/>. Content
        that is a fragment, such as the output of a subscription filter,
        a YANG Patch edit, or a configuration template, is expected to
        fail anydata-complete, and so is content from
        &lt;operational&gt;, in which semantic constraints may be
        violated (<xref section="5.3" target="RFC8342"/>). Such content
        is validated with anydata-candidate.</t>

        <t>A validator can use additional instance data of the
        datastore, such as a copy of it, to resolve references that
        leave the content. The content is then validated as part of
        that data tree. How such data is obtained is outside the scope
        of this document. Without such data, a reference to a node that
        is not in the data tree formed by the ancestors of the schema
        anchor and the content is not satisfied under anydata-complete
        and is not checked under anydata-candidate.</t>
      </section>

      <section anchor="validation-procedure">
        <name>Validation Procedure</name>

        <t>A validator validates one instance of an "anydata" node as
        follows:</t>

        <ol>
          <li>Perform the schema lookup of <xref
          target="lookup-procedure"/>. If the lookup ends in "invalid"
          or "not validated" (<xref target="lookup-outcomes"/>),
          validation ends with the same outcome.</li>

          <li>Instantiate the ancestors of the content from the schema
          anchor, including the key leafs given in its predicates, and
          place the content under the anchor.</li>

          <li>Apply the checks of the selected option (<xref
          target="validation-options"/>).</li>

          <li>For each nested "anydata" node in the content, repeat this
          procedure with the validation context of that node if one is
          available. Otherwise, its content is not validated (<xref
          target="nested-content"/>).</li>
        </ol>

        <t>A validator MUST support both options and MUST follow this
        procedure. A validator MUST NOT report content as invalid
        because context needed for the lookup or for validation is
        missing.</t>
      </section>

      <section anchor="validation-outcomes">
        <name>Outcomes and Error Reporting</name>

        <t>Validation of one instance of an "anydata" node ends in one
        of the outcomes of <xref target="lookup-outcomes"/>: valid,
        invalid, or not validated. A result also names the option that
        was applied, and lists any subtrees that were not validated.</t>

        <t>A validator reports errors with the "error-tag" and
        "error-app-tag" values that <xref target="RFC7950"/> already
        assigns to each violation, as listed in <xref
        target="validation-errors"/>. The "error-path" is the path from
        the root of the data tree, including the ancestors instantiated
        from the schema anchor.</t>

        <table anchor="validation-errors">
          <name>Validation errors</name>

          <thead>
            <tr>
              <th>Violation</th>

              <th>error-tag</th>

              <th>error-app-tag</th>

              <th>Option</th>
            </tr>
          </thead>

          <tbody>
            <tr>
              <td>Value does not match its type (<xref section="8.3.1"
              target="RFC7950"/>)</td>

              <td>invalid-value</td>

              <td>from the restriction, if any</td>

              <td>both</td>
            </tr>

            <tr>
              <td>Missing key leaf (<xref section="8.3.1"
              target="RFC7950"/>)</td>

              <td>missing-element</td>

              <td/>

              <td>both</td>
            </tr>

            <tr>
              <td>More than one case branch (<xref section="8.3.1"
              target="RFC7950"/>)</td>

              <td>bad-element</td>

              <td/>

              <td>both</td>
            </tr>

            <tr>
              <td>Node with a false "if-feature" (<xref section="8.3.1"
              target="RFC7950"/>), or "config false" in a conventional
              configuration datastore</td>

              <td>unknown-element</td>

              <td/>

              <td>both</td>
            </tr>

            <tr>
              <td>Node with a false "when" (<xref section="8.3.1"
              target="RFC7950"/>)</td>

              <td>unknown-element</td>

              <td/>

              <td>complete</td>
            </tr>

            <tr>
              <td>"unique" (<xref section="15.1"
              target="RFC7950"/>)</td>

              <td>operation-failed</td>

              <td>data-not-unique</td>

              <td>complete</td>
            </tr>

            <tr>
              <td>"max-elements" (<xref section="15.2"
              target="RFC7950"/>)</td>

              <td>operation-failed</td>

              <td>too-many-elements</td>

              <td>complete</td>
            </tr>

            <tr>
              <td>"min-elements" (<xref section="15.3"
              target="RFC7950"/>)</td>

              <td>operation-failed</td>

              <td>too-few-elements</td>

              <td>complete</td>
            </tr>

            <tr>
              <td>"must" (<xref section="15.4" target="RFC7950"/>)</td>

              <td>operation-failed</td>

              <td>must-violation, unless the statement has its own</td>

              <td>complete</td>
            </tr>

            <tr>
              <td>Leafref or instance-identifier without instance (<xref
              section="15.5" target="RFC7950"/>)</td>

              <td>data-missing</td>

              <td>instance-required</td>

              <td>complete</td>
            </tr>

            <tr>
              <td>Mandatory choice (<xref section="15.6"
              target="RFC7950"/>)</td>

              <td>data-missing</td>

              <td>missing-choice</td>

              <td>complete</td>
            </tr>

            <tr>
              <td>Mandatory leaf</td>

              <td>missing-element</td>

              <td/>

              <td>complete</td>
            </tr>
          </tbody>
        </table>

        <t>What a consumer does with the outcome is outside the scope of
        this document. A consumer can, for example, pass valid content
        on, discard or quarantine invalid content and alert an operator,
        and pass on content that was not validated while counting
        it.</t>
      </section>

      <section anchor="validation-example">
        <name>Example</name>

        <t>A YANG-Push subscription <xref target="RFC8641"/> to
        &lt;operational&gt; selects the interface statistics of <xref
        target="RFC8343"/>. The anchor of the "datastore-contents" node
        is "/", the datastore is &lt;operational&gt;, and the consumer
        chooses anydata-candidate. A network node with a software defect
        sends the following update:</t>

        <sourcecode type="xml"><![CDATA[
        <notification
            xmlns="urn:ietf:params:xml:ns:netconf:notification:1.0">
          <eventTime>2026-10-09T10:00:00Z</eventTime>
          <push-update xmlns="urn:ietf:params:xml:ns:yang:ietf-yang-push">
            <id>1011</id>
            <datastore-contents>
              <interfaces
                  xmlns="urn:ietf:params:xml:ns:yang:ietf-interfaces">
                <interface>
                  <name>eth0</name>
                  <statistics>
                    <in-octets>-4271233</in-octets>
                  </statistics>
                </interface>
              </interfaces>
            </datastore-contents>
          </push-update>
        </notification>
        ]]></sourcecode>

        <t>The lookup finds a schema node for every element. Step 3
        checks the value of "in-octets" against its type,
        "yang:counter64", whose range is 0 to 18446744073709551615. The
        value is outside that range, so the outcome is invalid, with
        error-tag "invalid-value" and error-path
        "/if:interfaces/if:interface[if:name='eth0']/if:statistics/if:in-octets".
        Because the update is a fragment, anydata-complete would also
        report the missing mandatory "type" leaf with error-tag
        "missing-element", even though the content is a correct part of
        &lt;operational&gt;.</t>
      </section>
    </section>

    <section anchor="Implementation" title="Implementation Status">
      <t>Note to the RFC-Editor: Please remove this section before
      publishing.</t>

      <t>anydata-candidate validation is implemented for libyang and
      available at <eref
      target="https://github.com/ahassany/libyang/tree/anydata-strict-parsing"/></t>
    </section>

    <section anchor="IANA">
      <name>IANA Considerations</name>

      <t>This memo includes no request to IANA.</t>
    </section>

    <section anchor="Security">
      <name>Security Considerations</name>

      <t>TBD</t>
    </section>
  </middle>

  <back>
    <references>
      <name>References</name>

      <references>
        <name>Normative References</name>

        <xi:include href="https://bib.ietf.org/public/rfc/bibxml/reference.RFC.2119.xml"/>

        <xi:include href="https://bib.ietf.org/public/rfc/bibxml/reference.RFC.8174.xml"/>

        <xi:include href="https://bib.ietf.org/public/rfc/bibxml/reference.RFC.7950.xml"/>

        <xi:include href="https://bib.ietf.org/public/rfc/bibxml/reference.RFC.7951.xml"/>

        <xi:include href="https://bib.ietf.org/public/rfc/bibxml/reference.RFC.8342.xml"/>

        <xi:include href="https://bib.ietf.org/public/rfc/bibxml/reference.RFC.8525.xml"/>

        <xi:include href="https://bib.ietf.org/public/rfc/bibxml/reference.RFC.9254.xml"/>

        <xi:include href="https://bib.ietf.org/public/rfc/bibxml/reference.RFC.9595.xml"/>

        <xi:include href="https://bib.ietf.org/public/rfc/bibxml/reference.RFC.8341.xml"/>

        <xi:include href="https://bib.ietf.org/public/rfc/bibxml/reference.RFC.6241.xml"/>

        <xi:include href="https://bib.ietf.org/public/rfc/bibxml/reference.RFC.8040.xml"/>

        <xi:include href="https://bib.ietf.org/public/rfc/bibxml/reference.RFC.8072.xml"/>
      </references>

      <references>
        <name>Informative References</name>

        <xi:include href="https://bib.ietf.org/public/rfc/bibxml/reference.RFC.8343.xml"/>

        <xi:include href="https://bib.ietf.org/public/rfc/bibxml/reference.RFC.9195.xml"/>

        <xi:include href="https://bib.ietf.org/public/rfc/bibxml/reference.RFC.8526.xml"/>

        <xi:include href="https://bib.ietf.org/public/rfc/bibxml/reference.RFC.9144.xml"/>

        <xi:include href="https://bib.ietf.org/public/rfc/bibxml/reference.RFC.8639.xml"/>

        <xi:include href="https://bib.ietf.org/public/rfc/bibxml/reference.RFC.8641.xml"/>

        <xi:include href="https://bib.ietf.org/public/rfc/bibxml/reference.RFC.8528.xml"/>

        <xi:include href="https://bib.ietf.org/public/rfc/bibxml/reference.RFC.6022.xml"/>

        <xi:include href="https://bib.ietf.org/public/rfc/bibxml/reference.RFC.7952.xml"/>

        <xi:include href="https://bib.ietf.org/public/rfc/bibxml/reference.RFC.8532.xml"/>

        <xi:include href="https://bib.ietf.org/public/rfc/bibxml/reference.RFC.8791.xml"/>

        <xi:include href="https://bib.ietf.org/public/rfc/bibxml3/reference.I-D.jouqui-netmod-yang-full-include.xml"/>

        <xi:include href="https://bib.ietf.org/public/rfc/bibxml3/reference.I-D.ietf-nmop-yang-message-broker-integration.xml"/>

        <xi:include href="https://bib.ietf.org/public/rfc/bibxml3/reference.I-D.tt-netmod-yang-config-templates.xml"/>

        <xi:include href="https://bib.ietf.org/public/rfc/bibxml3/reference.I-D.ietf-netconf-notif-envelope.xml"/>

        <xi:include href="https://bib.ietf.org/public/rfc/bibxml3/reference.I-D.ietf-netconf-yang-push-2.xml"/>

        <xi:include href="https://bib.ietf.org/public/rfc/bibxml3/reference.I-D.ietf-nmop-message-broker-telemetry-message.xml"/>
      </references>
    </references>

    <section anchor="Acknowledgements" numbered="false">
      <name>Acknowledgements</name>

      <t>The authors would like to thank Jean Quilbeuf, Benoit Claise,
      and Alex Huang Feng for their review and valuable comments.</t>
    </section>
  </back>
</rfc>
