<?xml version="1.0" encoding="utf-8"?>
<?xml-model href="rfc7991bis.rnc"?>
<rfc xmlns:xi="http://www.w3.org/2001/XInclude"
     docName="draft-hawkins-x402-dns-discovery-03"
     category="info"
     ipr="trust200902"
     submissionType="IETF"
     tocInclude="true"
     sortRefs="true"
     symRefs="true"
     version="3">

  <front>
    <title abbrev="x402 DNS Discovery">Discovering x402 Payment
    Capability via DNS and a Well-Known URI</title>
    <seriesInfo name="Internet-Draft"
                value="draft-hawkins-x402-dns-discovery-03"/>
    <author fullname="Walter D. Hawkins" initials="Walter D."
            surname="Hawkins">
      <organization>Independent</organization>
      <address>
        <email>wdhawkins46@gmail.com</email>
      </address>
    </author>
    <date year="2026" month="August" day="23"/>
    <area>Applications</area>
    <keyword>x402</keyword>
    <keyword>DNS</keyword>
    <keyword>well-known</keyword>
    <keyword>payments</keyword>
    <keyword>discovery</keyword>

    <abstract>
      <t>x402 is an application-level protocol for internet-native
      payments built on the HTTP 402 (Payment Required) status code.
      This document defines how a domain publishes its x402 payment
      capability out-of-band, so that clients, autonomous agents, and
      indexers can discover it without prior configuration or a central
      directory. It specifies a JSON capability manifest served at the
      well-known URI "/.well-known/x402" and an optional DNS TXT record
      at the underscored node name "_x402" that points to the manifest.
      A consumer resolves a bare domain name to verified x402
      capability with at most one DNS query and one HTTPS GET.</t>
    </abstract>

    <note removeInRFC="true">
      <name>About This Document</name>
      <t>This document is a successor to the expired individual
      submission draft-jeftovic-x402-dns-discovery-00, whose author is
      credited in the Acknowledgments; an offer of co-authorship
      remains open. Discussion of this document takes place in the
      x402 Foundation community
      (https://github.com/x402-foundation/x402), where a corresponding
      extension specification is under review.</t>
    </note>
  </front>

  <middle>
    <section anchor="intro">
      <name>Introduction</name>
      <t>The x402 protocol <xref target="X402"/> makes payment terms
      self-describing at the moment a client encounters an HTTP 402
      response: the response body enumerates acceptable payment
      schemes, networks, assets, and amounts. What x402 does not
      define is how a client that has never contacted a host learns
      that the host participates in x402 at all, in what role, and
      with what capabilities. In practice this gap has been filled by
      hand-curated lists and directory sites, which rot, do not scale,
      and centralize what is naturally edge-published data.</t>
      <t>Electronic mail solved the same problem with DNS records
      (MX, SPF <xref target="RFC7208"/>, DMARC
      <xref target="RFC7489"/>), and most directly with MTA-STS
      <xref target="RFC8461"/>, in which an unauthenticated DNS TXT
      record points to an authenticated HTTPS policy document. This
      document applies that pattern to x402:</t>
      <ul>
        <li>A JSON capability manifest served over HTTPS at the
        well-known URI <xref target="RFC8615"/> path
        "/.well-known/x402" is the authoritative, machine-readable
        record of a host's x402 capability
        (<xref target="manifest"/>).</li>
        <li>An optional DNS TXT record at the underscored node name
        <xref target="RFC8552"/> "_x402" is a lightweight pointer that
        lets a consumer discover x402 capability from DNS alone,
        before making any HTTP request (<xref target="txt"/>).</li>
      </ul>
      <t>A consumer resolves a bare domain name to verified capability
      with at most one DNS query and one HTTPS GET
      (<xref target="resolution"/>). Curated directories become
      optional caches, regenerable by crawling, rather than
      load-bearing infrastructure.</t>
    </section>

    <section anchor="conventions">
      <name>Conventions and Definitions</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>
      <dl>
        <dt>Facilitator:</dt>
        <dd>A service that verifies and settles x402 payments on
        behalf of resource servers, conventionally exposing
        "supported", "verify", and "settle" endpoints.</dd>
        <dt>Resource server:</dt>
        <dd>An HTTP server that gates resources behind x402
        payments.</dd>
        <dt>Manifest:</dt>
        <dd>The JSON document defined in <xref target="manifest"/>.</dd>
        <dt>Consumer:</dt>
        <dd>Any client, agent, crawler, or indexer that resolves x402
        capability using this mechanism.</dd>
      </dl>
    </section>

    <section anchor="manifest">
      <name>The x402 Well-Known URI</name>
      <t>A host participating in x402 SHOULD serve a JSON
      <xref target="RFC8259"/> manifest at:</t>
      <sourcecode type="text">
https://&lt;host&gt;/.well-known/x402
</sourcecode>
      <t>The manifest MUST be served over HTTPS with media type
      "application/json". Cross-origin GET SHOULD be permitted; the
      manifest is public data. Hosts SHOULD serve the manifest with
      HTTP caching headers.</t>

      <section anchor="manifest-example">
        <name>Example</name>
        <sourcecode type="json">
{
  "x402Version": 2,
  "kind": "facilitator",
  "name": "Example Facilitator",
  "description": "One-line human description.",
  "facilitator": {
    "baseUrl": "https://pay.example.com",
    "endpoints": {
      "supported": "/supported",
      "verify": "/verify",
      "settle": "/settle"
    },
    "kinds": [
      { "x402Version": 2, "scheme": "exact",
        "network": "eip155:114" }
    ],
    "assets": [
      {
        "network": "eip155:114",
        "address": "0x1F930B6A9F68c91aB23db07a9c4A5Dc166eF8011",
        "symbol": "EXUSD",
        "decimals": 6,
        "standard": "EIP-3009"
      }
    ]
  },
  "resources": [
    {
      "url": "https://pay.example.com/demo/card",
      "method": "POST",
      "description": "x402-paywalled demo resource"
    }
  ],
  "attestation": { "type": "none" },
  "docs": "https://pay.example.com/",
  "contact": "ops@example.com",
  "updated": "2026-08-04T00:00:00Z"
}
</sourcecode>
      </section>

      <section anchor="manifest-fields">
        <name>Field Semantics</name>
        <dl>
          <dt>x402Version (REQUIRED):</dt>
          <dd>Highest x402 protocol version the host speaks.</dd>
          <dt>kind (REQUIRED):</dt>
          <dd>One of "facilitator", "resource-server", or "both".</dd>
          <dt>name, description (RECOMMENDED):</dt>
          <dd>Human-readable identification.</dd>
          <dt>facilitator (REQUIRED when kind includes
          facilitator):</dt>
          <dd>Capability block for the facilitator role.</dd>
          <dt>facilitator.baseUrl (REQUIRED):</dt>
          <dd>HTTPS base URL of the facilitator API. It MUST be on
          the same domain as, or a subdomain of, the host serving the
          manifest, and consumers MUST reject manifests that violate
          this. Without this rule a host can name someone else's
          facilitator as its own and turn every conforming crawler
          into a request amplifier aimed at a third party.</dd>
          <dt>facilitator.endpoints (REQUIRED):</dt>
          <dd>Relative paths for the supported/verify/settle
          endpoints. Deployments differ; consumers do not guess.</dd>
          <dt>facilitator.kinds (REQUIRED):</dt>
          <dd>A mirror of the live "supported" endpoint. Divergence
          between the manifest and the live endpoint is a
          misconfiguration; consumers MUST prefer the live endpoint
          (<xref target="resolution"/>).</dd>
          <dt>facilitator.assets (RECOMMENDED):</dt>
          <dd>Settleable assets per network, with the token standard
          each scheme relies on.</dd>
          <dt>resources (OPTIONAL):</dt>
          <dd>x402-gated resources on this host. Each "url" MUST be
          HTTPS and on the manifest's own domain or a subdomain.
          Consumers MUST NOT dereference entries that are not, and
          SHOULD treat their presence as an abuse signal. Because
          this document invites indexers to fetch these URLs, an
          unconstrained field would constitute server-side request
          forgery by specification: a host listing an internal or
          link-local address would have every conforming crawler
          dereference it from inside the crawler's own network.</dd>
          <dt>attestation (OPTIONAL):</dt>
          <dd>Execution-integrity claims, e.g. {"type":"none"} or
          {"type":"tee","scheme":"...","verifier":"&lt;url&gt;"}. See
          <xref target="security"/>.</dd>
          <dt>updated (RECOMMENDED):</dt>
          <dd>Timestamp <xref target="RFC3339"/> of the last manifest
          change, used for cache decisions alongside HTTP caching
          headers.</dd>
        </dl>
        <t>Unknown fields MUST be ignored, for forward
        compatibility.</t>
      </section>
    </section>

    <section anchor="txt">
      <name>The _x402 DNS TXT Record</name>
      <t>A domain MAY additionally publish a TXT record
      <xref target="RFC1035"/> at the underscored node name
      "_x402" <xref target="RFC8552"/>:</t>
      <sourcecode type="dns-rr">
_x402.example.com. IN TXT ( "v=x402-1; "
  "wk=https://pay.example.com/.well-known/x402; "
  "k=facilitator; net=eip155:114; scheme=exact" )
</sourcecode>
      <t>The RDATA is a single character-string sequence interpreted
      as semicolon-separated key=value pairs, order-insensitive:</t>
      <t>A TXT record longer than 255 octets is carried as multiple
      character-strings <xref target="RFC1035"/>, as the example above
      is. Consumers MUST concatenate the character-strings of a record
      with no separator, and MUST NOT insert whitespace between them,
      before parsing the result. SPF <xref target="RFC7208"/> fixes the
      same rule for the same reason. Without it two conformant
      implementations reading identical bytes derive different "wk"
      URLs -- one joining with the empty string and one with a space --
      and therefore disagree about where a domain's manifest lives,
      with neither able to detect the disagreement. Character-strings
      MUST NOT be reordered; the concatenation is in wire order.</t>
      <t>The failure is easy to miss in testing. Where a split happens
      to fall on a "; " boundary, a space-joining consumer still parses
      the record correctly, because the surrounding whitespace is
      trimmed. The divergence appears only when the 255-octet boundary
      falls inside a key or a value -- which is precisely the case the
      publisher does not choose and cannot see. An implementation with
      the wrong joiner passes every hand-written example and fails on
      the first record long enough for DNS to split it somewhere
      inconvenient, resolving "wk" to a host the publisher never
      named.</t>
      <dl>
        <dt>v (REQUIRED):</dt>
        <dd>The record format version. This document defines
        "x402-1".</dd>
        <dt>wk (REQUIRED):</dt>
        <dd>Absolute HTTPS URL of the manifest. It MUST be on the
        publishing domain or a subdomain of it (see
        <xref target="security"/>).</dd>
        <dt>k (RECOMMENDED):</dt>
        <dd>"facilitator", "resource-server", or "both" -- a coarse
        filter so crawlers can skip fetches.</dd>
        <dt>net (OPTIONAL):</dt>
        <dd>Comma-separated network identifiers (coarse filter
        only).</dd>
        <dt>scheme (OPTIONAL):</dt>
        <dd>Comma-separated scheme names (coarse filter only).</dd>
      </dl>
      <t>A domain MUST publish at most one record with "v=x402-1" at
      a given owner name. Consumers that find more than one MUST
      treat the name as unresolvable rather than choosing between
      them: "first record wins" is a race that anyone able to add a
      single TXT record can win by ordering -- a shared DNS control
      panel, a delegated subdomain, a partial compromise. SPF
      <xref target="RFC7208"/> and DMARC <xref target="RFC7489"/>
      both make duplicate records a hard error for precisely this
      reason.</t>
      <t>The TXT record is a pointer, not an authority: all
      capability data comes from the manifest, which is retrieved
      over HTTPS. This split -- unauthenticated DNS pointer to
      authenticated HTTPS policy -- is the MTA-STS
      <xref target="RFC8461"/> pattern, and it keeps the mechanism
      useful even where DNSSEC <xref target="RFC4033"/> is absent.</t>
      <t>Hosts without control of their DNS (for example, hosts on
      platform-assigned subdomains) simply publish the manifest
      alone; resolution step 2 below still finds them.</t>
    </section>

    <section anchor="which-name">
      <name>Determining D from a Resource URL</name>
      <t>Revision -01 specified the record at "_x402.D" without saying
      how a consumer holding a RESOURCE URL determines D. That omission
      is not theoretical. A survey of 1,609 hosts listed in a public
      x402 catalogue on 2026-08-22 queried "_x402.&lt;exact-host&gt;"
      and recorded this document's own author as publishing nothing:
      the record is at the apex, and its "wk" target is a service
      subdomain. Publishing at the apex is the natural arrangement for
      an operator with one DNS zone and several service hosts, so the
      narrow reading makes a conforming publisher invisible.</t>
      <t>Consumers therefore MUST query the resource host first, and
      SHOULD then query ancestor names, nearest first, stopping at the
      first name that yields a usable record. Implementations SHOULD
      bound this at two ancestors and MUST NOT query a name of fewer
      than two labels. The walk is SHOULD rather than MAY because two
      conforming consumers holding the same resource URL must not reach
      different answers about the same publisher, which is the failure
      this section opens by describing; a consumer that skips it is
      expected to have a reason, such as only ever holding apex names,
      not merely permission.</t>
      <t>An ancestor's record introduces a hazard that the narrow
      reading did not have. Under a shared hosting suffix the ancestor
      is controlled by the platform rather than the tenant, so a single
      record would otherwise make every name beneath it discoverable —
      including tenants that published nothing and names that do not
      resolve at all. The same survey confirmed this against the
      author's own zone: an invented subdomain inherited the apex
      record.</t>
      <t>Accordingly, a manifest obtained from an ancestor name A
      applies to a host H (where H is A or a subdomain of A) ONLY if
      the manifest itself references H, in "facilitator.baseUrl" or in
      an entry of "resources". A referenced URL counts only when its
      host is itself A or a subdomain of A. If the manifest does not
      reference H, the consumer MUST treat discovery as having failed
      for H rather than attributing the ancestor's capability to it.
      A manifest retrieved from H itself always applies to H.</t>
      <t>This rule deliberately avoids depending on a public suffix
      list. Such a list is a mutable external dependency, it does not
      agree with operational reality for privately delegated suffixes,
      and an error in it converts silently into a false claim that a
      host is discoverable. Requiring the zone operator to name the
      host is a positive statement by a party in a position to make
      it.</t>
      <t>That justification describes a ZONE operator, and under a
      shared suffix the zone operator is not the host's operator. In a
      walk of 2,234 distinct names over 1,611 catalogued hosts on
      2026-08-23, 381 hosts (23.6 percent) reach an ancestor name that
      is itself a public suffix - "workers.dev", "vercel.app", "up.railway.app", "onrender.com", "fly.dev", and 23 further
      names. None of the 28 suffixes so reached carries an "_x402"
      record, so the hazard is prospective rather than present: were a
      record to appear at one, every tenant beneath it would inherit
      it. It is the naming rule above, not an assumption about who
      controls the ancestor, that keeps this safe. Revision -02 said
      "the only party", which overstates it: on a shared suffix the
      party who can add the record and the party whose capability is
      being asserted are different people.</t>
      <t>These counts are exact for the frame walked and are not
      comparable across frames: the sampling frame is a window on a
      catalogue that turns over daily, not a cohort. The walk, that
      frame, its digest ("25e61f5433b13f7b"), the full host list, and the pinned
      public suffix list the walk was computed against are published
      in <xref target="WALK"/>, so a reader can recompute every number
      in this section rather than take it. Only one quantity there is
      observed over the network - whether a reached suffix carries a
      record - and it is published as an interval for that reason.</t>
    </section>

    <section anchor="resolution">
      <name>Resolution Algorithm</name>
      <t>Comparing host names. Every comparison of two host names in this document - a
        "wk" URL's host against D, a referenced URL's host against an
        ancestor A, a host H against A - is a comparison of DNS names,
        not of octet strings. Consumers MUST compare case-insensitively,
        on A-labels (an internationalized name is converted per IDNA
        before comparing, so a U-label and its A-label are the same
        name), and ignoring a trailing dot ("api.example.com." and
        "api.example.com" are the same name). A comparison that treats
        any of those pairs as different fails closed: it scores a
        conforming publisher's "wk" as out-of-domain and drops that
        publisher from discovery with nothing logged, which is the
        failure direction nobody reports.</t>
      <t>Given a domain name D determined per
      <xref target="which-name"/>, a consumer resolves x402 capability
      as follows:</t>
      <ol>
        <li>Query TXT for "_x402.D". If a record with "v=x402-1"
        exists, fetch the manifest from its "wk" URL, rejecting
        non-HTTPS or out-of-domain URLs. A record that fails to parse
        under the grammar in <xref target="txt"/> is treated as
        absent, not as an error. Consumers MUST ask whether a TXT
        record was returned THAT PARSES, rather than whether the query
        returned an answer: under a wildcard-CNAME zone, "_x402.D"
        answers NOERROR with a CNAME and no TXT record at all, which a
        reader testing only the response code scores as a record. An
        independent reader mis-scored 170 names this way before the
        distinction was drawn. Consumers MUST re-apply the
        in-domain constraint to every redirect hop and report the
        final URL as the manifest source. Checking only the requested
        URL validates a location the bytes need not have come from:
        an in-domain "wk" URL that redirects off-domain would
        otherwise pass, defeating the one control the
        (unauthenticated) DNS layer has. Redirect chains SHOULD be
        bounded.</li>
        <li>Otherwise, attempt GET on
        "https://D/.well-known/x402".</li>
        <li>Validate the manifest shape; ignore unknown fields.</li>
        <li>Before using a facilitator, fetch the live "supported"
        endpoint given by baseUrl and endpoints.supported, and treat
        the live response as authoritative over the manifest's
        "kinds" array.</li>
      </ol>
      <t>Steps 1-2 answer "does this domain speak x402, and in what
      role" with at most one DNS query and one HTTP GET. Indexers
      crawl the same way and SHOULD periodically re-verify
      records.</t>

      <section anchor="fetch-bounds">
        <name>Fetch Bounds</name>
        <t>Consumers MUST bound the manifest fetch with a request
        timeout and a maximum response size. An unbounded read is a
        denial of service handed to anyone who can publish a TXT
        record: a hostile host serves an arbitrarily large body, or
        trickles bytes indefinitely, and the crawler exhausts memory
        or hangs. Size limits MUST be applied to the bytes actually
        received, not to the Content-Length header, which is the
        server's claim rather than a measurement. (One deployed
        implementation uses a 256 KiB size cap, a 10-second deadline,
        and at most 3 redirect hops.)</t>
      </section>

      <section anchor="private-dest">
        <name>Refusing Private Destinations</name>
        <t>Before every fetch this document invites -- the manifest,
        each redirect hop, resources[] probes, and the live
        "supported" cross-check -- a consumer MUST refuse a URL whose
        host is, or resolves to, a loopback, link-local, or
        private-range address. The HTTPS and in-domain rules do not
        cover this case: the publisher controls their own DNS, so an
        in-domain hostname can resolve to a link-local metadata
        address or an address inside the crawler's network, and
        DNS-based certificate issuance grants valid certificates to
        names that never point anywhere public. The check MUST be
        re-applied on every redirect hop; a public first hop
        redirecting to an internal name is the classic bypass.
        Resolution-time checks remain subject to DNS rebinding
        between check and connect; consumers needing a stronger
        guarantee SHOULD pin the resolved address for the connection.
        Deployments intentionally operating on private networks MAY
        relax this rule, explicitly.</t>
      </section>
    </section>

    <section anchor="security">
      <name>Security Considerations</name>
      <t>Discovery is not endorsement. A manifest proves that a host
      claims a capability; it transfers no trust. Clients MUST
      validate settlement the way the x402 protocol already requires,
      and SHOULD apply their own reputation or allowlist policy on
      top of discovery.</t>
      <t>DNS spoofing: the TXT record is unauthenticated without
      DNSSEC. That is why it may only point into the same domain, and
      why the manifest -- served under the domain's TLS certificate --
      is the authority. An attacker who can forge the TXT record but
      not the domain's HTTPS gains nothing.</t>
      <t>The same-origin constraint on "wk" prevents a domain from
      claiming another operator's facilitator as its own, and
      prevents the record from being used as an open redirect for
      crawler traffic. This holds only if consumers enforce it on
      every redirect hop and on facilitator.baseUrl, not on the
      requested URL alone.</t>
      <t>Servers MUST NOT derive manifest URLs from
      request-controlled input. A manifest endpoint that builds its
      own baseUrl or resource URLs from the Host or X-Forwarded-Host
      request headers lets any caller make the document -- served
      under the operator's own TLS certificate -- advertise an
      attacker's host, and a cacheable response without a matching
      Vary header can then be replayed to other consumers. The public
      origin MUST be pinned in configuration. This is the same attack
      the "wk" rule addresses, arriving on the side this document
      calls authoritative, and it is easy to introduce precisely
      because deriving the origin from the request looks like good
      hygiene.</t>
      <t>DNSSEC upgrades the TXT record from a hint to an assertion.
      Unsigned, the record is a convenience that the HTTPS manifest
      must backstop. Signed, a validating resolver can prove the
      record was not tampered with. Operators SHOULD sign zones
      carrying "_x402" records and SHOULD monitor RRSIG expiry: an
      expired signature fails validation exactly like a forged one,
      so the record -- and the discovery path -- disappears on a
      timer.</t>
      <t>Manifest/live divergence: consumers MUST prefer live
      "supported" data over the manifest's mirror of it; indexers
      SHOULD flag divergent hosts.</t>
      <t>Attestation claims in the manifest are claims like
      everything else: an execution-integrity attestation is only
      meaningful if the verifier URL lets the client independently
      check an attestation token chain against a published,
      reproducible build. Absent such verification, consumers treat
      the attestation as absent.</t>
      <t>Crawler load: manifests are static JSON; hosts SHOULD serve
      them with cache headers and rate-limit them as any public
      endpoint.</t>
    </section>

    <section anchor="iana">
      <name>IANA Considerations</name>
      <section anchor="iana-wk">
        <name>Well-Known URI Registration</name>
        <t>IANA is requested to register the following entry in the
        "Well-Known URIs" registry defined by
        <xref target="RFC8615"/>:</t>
        <dl>
          <dt>URI Suffix:</dt><dd>x402</dd>
          <dt>Change Controller:</dt>
          <dd>Walter D. Hawkins &lt;wdhawkins46@gmail.com&gt;</dd>
          <dt>Reference:</dt><dd>This document</dd>
          <dt>Status:</dt><dd>provisional</dd>
        </dl>
        <t>Two corrections to the request made in revision -01 of this
        document, both of the author's own making.</t>
        <t>That revision named IETF as the change controller.
        <xref target="RFC8615"/>, Section 3.1 states: "For Standards Track
        RFCs, state 'IETF'. For others, give the name of the responsible
        party." This document is an individual submission and is not a
        Standards Track RFC, so the responsible party is the author, and
        the earlier entry asserted an institutional change control that
        does not exist.</t>
        <t>That revision also requested permanent status.
        <xref target="RFC8615"/>, Section 3.1 reserves permanent status for
        values "defined by Standards Track RFCs and other open standards",
        and directs that "other values should be registered as
        'provisional'". Provisional is the correct status for this
        registration, and provisional entries may be removed by the experts
        if they are found not to be in use — an outcome the author accepts
        as appropriate for a suffix that has not yet been shown to be
        widely deployed.</t>
        <t>The suffix registered here is the name of a payment protocol
        developed elsewhere. Should the x402 project, or a body acting on
        its behalf, wish to assume change control of this registration,
        the author will support that reassignment; nothing in this document
        is intended to claim authority over the protocol's name.</t>
      </section>
      <section anchor="iana-underscore">
        <name>Underscored Node Name Registration</name>
        <t>IANA has registered the following entry in the "Underscored and
        Globally Scoped DNS Node Names" registry defined by
        <xref target="RFC8552"/>. The allocation was made on 2026-08-11 and
        is recorded here for completeness; no further action is requested.</t>
        <dl>
          <dt>RR Type:</dt><dd>TXT</dd>
          <dt>_NODE NAME:</dt><dd>_x402</dd>
          <dt>Reference:</dt><dd>This document</dd>
        </dl>
      </section>
    </section>

    <section anchor="changes-03" removeInRFC="true">
      <name>Changes Since -02</name>
      <t>Both changes below originate in the x402 Foundation extension
      specification, where the same rules are restated for
      implementers. That document declares this draft normative and
      itself the defect when they disagree; these two paragraphs were
      corrected there first, which made the better text formally the
      defect. This revision carries them back, so the direction of
      authority and the direction of correctness agree again.</t>
      <ul>
        <li>Resolution Algorithm: consumers MUST ask whether a TXT
        record was returned THAT PARSES, not whether the query
        returned an answer. A wildcard-CNAME zone answers NOERROR with
        a CNAME and no TXT, which a reader testing the response code
        scores as a record; this mis-scored 170 names in an
        independent reader's first pass. Revision -02 contained no
        occurrence of CNAME, NOERROR or wildcard.</li>
        <li>Determining D from a Resource URL: "the only party in a
        position to make it" is corrected to "a party in a position to
        make it", with an implementer note in <xref target="which-name"/>
        recording that under a shared suffix the zone operator is not
        the host's operator, and quantifying how often such an
        ancestor is reachable at all. The counts live in that section
        and in the artifact it cites, and are deliberately not
        restated here: a number written twice is a number that will
        one day disagree with itself, and the stale copy is always the
        hand-written one.</li>
        <li>Determining D from a Resource URL: the ancestor walk is
        SHOULD rather than MAY. Under MAY, two conforming consumers
        holding one resource URL could reach different answers about
        one publisher - the non-determinism the section opens by
        diagnosing - and an optional path that benefits nobody today
        does not get implemented, so it is absent on the day a
        publisher needs it. Raised by an independent reviewer of the
        x402 Foundation extension.</li>
        <li>Resolution Algorithm: a new opening paragraph on comparing host names -
        case-insensitive, on A-labels, ignoring a trailing dot. Revision
        -02 did not say, and a reference implementation was found to
        apply those rules asymmetrically - normalizing one side of a
        comparison and not the other - so that a name did not equal
        itself and a conforming publisher was dropped silently. Found
        by the same reviewer; the defect was real, not hypothetical.</li>
      </ul>
    </section>

    <section anchor="changes-02" removeInRFC="true">
      <name>Changes Since -01</name>
      <ul>
        <li>Well-Known URI Registration: corrected the change controller
        from IETF to the author. An individual submission cannot name IETF as change
        controller (<xref target="RFC8615"/>, Section 3.1).</li>
        <li>Well-Known URI Registration: changed the requested status from
        permanent to provisional, per the same section.</li>
        <li>Well-Known URI Registration: added a statement that change
        control of the suffix may be reassigned to the x402 project or a body acting on
        its behalf.</li>
        <li>Underscored Node Name Registration: the node name <tt>_x402</tt> was
        allocated by IANA on 2026-08-11; the section now records the
        completed registration rather than requesting it.</li>
        <li>New section: "Determining D from a Resource URL". Revision
        -01 never said which name a consumer holding a resource URL
        should query. Adds the host-then-ancestor order, and the rule
        that an ancestor's manifest applies to a host only if it names
        that host — without which a shared-hosting platform's record
        would vouch for every tenant beneath it.</li>
      </ul>
    </section>

    <section anchor="impl-status" removeInRFC="true">
      <name>Implementation Status</name>
      <t>This section records the status of known implementations per
      <xref target="RFC7942"/>.</t>
      <ul>
        <li>A zero-dependency resolver implementing the full
        algorithm of <xref target="resolution"/>, including redirect
        re-validation, fetch bounds, and private-destination refusal,
        is deployed and exercises live "_x402" records published on
        the author's production domains, resolving end-to-end from
        bare domain name to live capability endpoint.</li>
        <li>A corresponding extension specification is under review
        in the x402 Foundation repository
        (x402-foundation/x402, pull request 2979), with a live
        manifest served by a public facilitator deployment.</li>
      </ul>
    </section>

    <section anchor="prior">
      <name>Relationship to Prior Proposals</name>
      <t>DNS-based and well-known-URI-based discovery for x402 has
      been proposed independently several times in the x402
      community, most completely in
      <xref target="JEFTOVIC"/>, which used the same "_x402" TXT
      label and substantially the same resolution approach. That
      document expired without revision in May 2026. This document is
      offered as a successor that consolidates those proposals and
      adds the manifest schema, duplicate-record rule, redirect and
      private-destination constraints, and IANA registrations.
      Co-authorship remains open to the authors of the prior
      proposals.</t>
    </section>
  </middle>

  <back>
    <references>
      <name>References</name>
      <references anchor="normative">
        <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.1035.xml"/>
        <xi:include href="https://bib.ietf.org/public/rfc/bibxml/reference.RFC.8259.xml"/>
        <xi:include href="https://bib.ietf.org/public/rfc/bibxml/reference.RFC.8552.xml"/>
        <xi:include href="https://bib.ietf.org/public/rfc/bibxml/reference.RFC.8615.xml"/>
        <xi:include href="https://bib.ietf.org/public/rfc/bibxml/reference.RFC.3339.xml"/>
      </references>
      <references anchor="informative">
        <name>Informative References</name>
        <xi:include href="https://bib.ietf.org/public/rfc/bibxml/reference.RFC.4033.xml"/>
        <xi:include href="https://bib.ietf.org/public/rfc/bibxml/reference.RFC.7208.xml"/>
        <xi:include href="https://bib.ietf.org/public/rfc/bibxml/reference.RFC.7489.xml"/>
        <xi:include href="https://bib.ietf.org/public/rfc/bibxml/reference.RFC.7942.xml"/>
        <xi:include href="https://bib.ietf.org/public/rfc/bibxml/reference.RFC.8461.xml"/>
        <reference anchor="X402" target="https://github.com/x402-foundation/x402">
          <front>
            <title>x402: An Open Standard for Internet-Native
            Payments</title>
            <author><organization>x402 Foundation</organization></author>
            <date year="2026"/>
          </front>
        </reference>
        <reference anchor="WALK" target="https://github.com/whawk46/x402-discovery-checks">
          <front>
            <title>x402 discovery checks: ancestor-walk census
            (conformance/ancestor-walk.json)</title>
            <author><organization>x402 discovery
            checks</organization></author>
            <date year="2026" month="August"/>
          </front>
          <refcontent>Artifact carries its sampling frame, the frame's
          sha256 digest, the sorted host list, and the pinned public
          suffix list with its own source and digest</refcontent>
        </reference>
        <reference anchor="JEFTOVIC" target="https://datatracker.ietf.org/doc/draft-jeftovic-x402-dns-discovery/">
          <front>
            <title>Discovering x402 Resources via DNS TXT
            Records</title>
            <author initials="M. E." surname="Jeftovic"
                    fullname="Mark E. Jeftovic"/>
            <date year="2025" month="November"/>
          </front>
          <refcontent>Work in Progress, expired
          Internet-Draft</refcontent>
        </reference>
      </references>
    </references>

    <section anchor="ack" numbered="false">
      <name>Acknowledgments</name>
      <t>Mark E. Jeftovic proposed "_x402" TXT-record discovery for
      x402 first, in <xref target="JEFTOVIC"/> and in x402 community
      discussion; this document deliberately builds on that work, and
      the offer to fold this text into a revision of his draft -- or
      to add him as co-author here -- stands. The authors of the other
      independent discovery proposals in the x402 community
      (repository issues 1348, 2582, and 2831) reached similar
      designs and are acknowledged likewise. Reviewers on x402
      Foundation pull request 2979 materially improved the security
      considerations, in particular the redirect re-validation and
      duplicate-record rules.</t>
    </section>
  </back>
</rfc>
