is it dns? / wiki ← back to the live monitor

HTTPS / SVCB: service binding hints

A modern record that lets DNS hand a client the parameters needed to start a TLS connection in one round trip: ALPN, port, IP hints, even ECH keys. HTTPS is just SVCB specialized for https:// URLs.

Type number65 (HTTPS) · 64 (SVCB)
RFC9460
RDATApriority · target · key=value pairs

What it holds#

Three slots:

FieldPurpose
Priority0 = "alias mode" (treat target as a CNAME-replacement). >0 = "service mode": these are real hints.
TargetThe hostname providing the service. In service mode, . (a single dot) means "this name itself." In alias mode, . means "this service does not exist" (RFC 9460 s2.5).
Parameterskey=value pairs the client uses to set up the connection.

The big parameters:

KeyCarries
alpnSupported ALPN protocols, e.g., h2, h3
portOverride the default port
ipv4hintIPv4 addresses the client can skip A lookups for
ipv6hintSame for v6
echEncrypted Client Hello config: opaque base64 blob the client uses

A real example, live on the demo name:

svcb.example.isitdns.net.   HTTPS  1 . alpn="h2,h3" ipv4hint=192.0.2.1 ipv6hint=2001:db8::1

Browsers reading that know, before they open a TCP connection, that:

  • The server speaks HTTP/2 and HTTP/3.
  • The addresses are 192.0.2.1 and 2001:db8::1: no waiting on separate A/AAAA lookups before it can connect.

This site itself (isitdns.net) also publishes a live HTTPS record with real ECH data. See the dig example section below for a runnable proof.

When to use it#

  • For any production web service. Modern browsers (Safari, Chrome, Firefox all support it) save a round trip when HTTPS hints are present.
  • To advertise ALPN+ECH together: required for the new privacy-preserving TLS handshake (Encrypted Client Hello).
  • To express "use port 8443" without resorting to a URL-with-port: port=8443 in the HTTPS record.

When not to use it#

  • For non-web services: use SVCB with its own service binding scheme, not HTTPS.
  • When your authoritative server cannot emit it. Older server versions lack native HTTPS/SVCB support; fall back to publishing the underlying A/AAAA + ALPN hints as separate records, or stand up the record as a generic typed RR (TYPE65) by hex-encoding the RDATA.
  • When the parameters change frequently: every change is a TTL-cache rollout.

dig example#

dig 9.10.x (stock macOS) does NOT know the name HTTPS as a query type. If you write dig example.com HTTPS, dig 9.10.x treats HTTPS as a second hostname and queries for the A record of the literal name HTTPS. instead. Use TYPE65 (the numeric form) on any dig older than BIND 9.16.21, the release that taught dig and nslookup both record types.

dig @1.1.1.1 svcb.example.isitdns.net TYPE65 +short

On an older dig the answer comes back as raw generic RDATA (a modern dig decodes it; add +unknownformat to reproduce this hex view on a dig that already understands the type):

\# 41 0001000001000602683202683300040004C00002010006001020010D B8000000000000000000000001

That hex is the raw RDATA of the HTTPS record. A dig that understands HTTPS (9.16.21 or newer) decodes it into 1 . alpn="h2,h3" ipv4hint=192.0.2.1 ipv6hint=2001:db8::1. The ipv4hint and ipv6hint here are documentation addresses (192.0.2.1 from TEST-NET-1, 2001:db8::1 from the IPv6 documentation prefix); this demo name publishes no A or AAAA records of its own, only the HTTPS record carrying the hints. The mechanism they demonstrate is real: on a production name the hints carry the actual edge IPs, kept in sync with the name's A/AAAA, so the client can open the connection without a separate address lookup.

Whether nslookup decodes SVCB/HTTPS depends on its BIND version, same as dig. BIND 9.16.21 added parsing and printing for both record types, so a modern nslookup shows the parameters. Older builds (like the 9.10-era stock macOS one) return raw hex just like dig 9.10.x; there, use dig 9.18+ or curl DoH instead.

nslookup -type=TYPE65 svcb.example.isitdns.net 1.1.1.1

A modern nslookup (9.18.39 shown, checked live against the demo name) decodes the record:

Server:    1.1.1.1
Address:   1.1.1.1#53

Non-authoritative answer:
svcb.example.isitdns.net  rdata_65 = 1 . alpn="h2,h3" ipv4hint=192.0.2.1 ipv6hint=2001:db8::1

Authoritative answers can be found from:

An nslookup older than 9.16.21 prints the same answer as raw hex:

svcb.example.isitdns.net  rdata_65 = \# 41 0001000001000602683202683300040004C00002010006001020010D B8000000000000000000000001

Proof with curl DoH#

curl is the most portable way to query HTTPS/SVCB from any machine, and it reports the AD bit so you can see whether the answer is DNSSEC-validated. How the record is printed depends on the provider: Cloudflare's JSON API returns type 65 as raw generic hex, while Google's decodes the parameters, which makes the pair a handy cross-check:

curl -s -H 'accept: application/dns-json' \
  'https://cloudflare-dns.com/dns-query?name=svcb.example.isitdns.net&type=HTTPS' \
  | jq .Answer

The data line below is long on purpose: the raw RDATA hex is the payload, so it stays unwrapped. Let it scroll. The TTL counts down from the zone's 300 while the answer sits in the resolver's cache; a cache miss shows the full 300.

[
  {
    "name": "svcb.example.isitdns.net",
    "type": 65,
    "TTL": 300,
    "data": "\\# 41 00 01 00 00 01 00 06 02 68 32 02 68 33 00 04 00 04 c0 00 02 01 00 06 00 10 20 01 0d b8 00 00 00 00 00 00 00 00 00 00 00 01"
  }
]

Google's JSON API returns the same record already decoded (note it skips the quotes around alpn that dig adds):

curl -s 'https://dns.google/resolve?name=svcb.example.isitdns.net&type=65' | jq -r '.Answer[].data'
1 . alpn=h2,h3 ipv4hint=192.0.2.1 ipv6hint=2001:db8::1

ECH in the wild: isitdns.net itself#

isitdns.net publishes a live HTTPS record that includes an ECH key blob and real Cloudflare edge addresses. You can fetch it with:

curl -s -H 'accept: application/dns-json' \
  'https://cloudflare-dns.com/dns-query?name=isitdns.net&type=HTTPS' \
  | jq '{AD: .AD, Answer: .Answer}'

Again, the data line is long on purpose: 136 bytes of raw RDATA is the point. Cloudflare also rotates the ECH key regularly, so the ech bytes in your output will differ from this capture (taken 2026-07-16):

{
  "AD": true,
  "Answer": [
    {
      "name": "isitdns.net",
      "type": 65,
      "TTL": 300,
      "data": "\\# 136 00 01 00 00 01 00 06 02 68 33 02 68 32 00 04 00 08 68 15 38 d3 ac 43 9b f2 00 05 00 47 00 45 fe 0d 00 41 2a 00 20 00 20 d1 0f 1e a0 59 58 8e b4 50 27 2d 1e 7e 16 2d e1 29 a9 f1 e4 ce f0 bb 63 0d 58 ff 5d 97 de 40 2d 00 04 00 01 00 01 00 12 63 6c 6f 75 64 66 6c 61 72 65 2d 65 63 68 2e 63 6f 6d 00 00 00 06 00 20 26 06 47 00 30 32 00 00 00 00 00 00 68 15 38 d3 26 06 47 00 30 36 00 00 00 00 00 00 ac 43 9b f2"
    }
  ]
}

The AD: true flag confirms DNSSEC validation passed end-to-end. Inside the hex blob you can read key 0x0001 (alpn: h3, h2), key 0x0004 (ipv4hint: 104.21.56.211 and 172.67.155.242), key 0x0005 (ech: a 71-byte opaque config), and key 0x0006 (ipv6hint). This is what a real production HTTPS record with ECH looks like on the wire.

DoH query over HTTPS transport#

DoH is DNS-over-HTTPS, documented in dot-doh. The curl commands above already use DoH through Cloudflare's JSON API. dig 9.18+ can speak the binary wire format from RFC 8484 directly with +https:

dig @1.1.1.1 +https svcb.example.isitdns.net HTTPS +short
1 . alpn="h2,h3" ipv4hint=192.0.2.1 ipv6hint=2001:db8::1

+https requires dig 9.18+ and is not available in the system dig on macOS (9.10.x).

nslookup can't issue DoH or DoT queries at any version. Use curl (shown above) or kdig from the knot-dnsutils package.

Gotchas#

  • Alias mode (priority 0) is a cname alternative at the apex. Useful because, unlike CNAME, HTTPS records can coexist with other apex records. Some managed DNS providers use this in front of proxied apex names.
  • ECH support requires the matching key at the origin. The published ech blob is the public half of a key config; the server must hold the private half. Do not publish ech=... until the server actually accepts it; some clients hard-fail rather than fall back.
  • Older resolvers may not pass HTTPS records through. EDNS UDP buffer size matters; large parameter blobs can truncate. See query-types for more on EDNS.
  • Browser support is good but not universal. Always still publish A/AAAA: HTTPS is additional hint data, not a replacement.
  • The ipv4hint/ipv6hint values must match the A/AAAA, or clients get inconsistent answers. They are hints, not gospel: RFC 9460 s7.3 tells clients to ignore them when A/AAAA answers are already in hand and to switch to the real addresses once they arrive. Managed DNS providers that auto-publish HTTPS records keep them in sync; for manually published records, you own the synchronization.
  • dig 9.10.x (stock macOS) silently ignores your intent. Writing dig example.com HTTPS on an older dig queries the A record for example.com and then the A record for the literal hostname HTTPS.. Always use TYPE65 on older dig, or see nslookup-and-dig for a newer dig.

See also#