A surprise breaking change! 1.1.1.1's DoH JSON API changes how records are displayed
Hi, I'm Shiichan! Today I found an update around Cloudflare's 1.1.1.1, so let's dig in!
Cloudflare ChangelogWhat was announced?
The Cloudflare Changelog announced a format update for the response returned by the DoH JSON API (application/dns-json) that 1.1.1.1 provides. During the rollout, responses may come back in either the old or the new format.
The post is explicit about this:
These are breaking changes. The DoH JSON format has no formal RFC and its schema is not guaranteed to be stable.
In other words, precisely because this format has no formal RFC, Cloudflare is free to change it at its own discretion.
The story so far
Until now, record types like CAA, NAPTR, RP, IPSECKEY, SVCB, HTTPS, TLSA, SSHFP, and OPENPGPKEY returned their data field using RFC 3597 generic hex encoding (\# {length} {hex}). It was essentially a raw byte string that meant nothing to a human reader.
DNSSEC-related records — RRSIG, DS, CDS, DNSKEY, and CDNSKEY — also displayed their algorithm as a mnemonic string, like RSASHA256.
What changes
With this update, the affected record types now come back in a standard, human-readable presentation format. Developers who used to decode that opaque hex data themselves no longer need to.
On the flip side, DNSSEC algorithms switch from mnemonic names to numeric identifiers, so any code that was doing string comparisons against something like RSASHA256 could break. If you're building a client or tool on top of the DoH JSON API, it's worth reviewing your parsing logic.
Dive Deep
Here's what the new presentation format looks like.
CAA: 0 issue "letsencrypt.org"
NAPTR: 100 10 "s" "SIP+D2U" "" _sip._udp.example.com.
RP: admin.example.com. txt.example.com.
IPSECKEY: 10 1 2 192.0.2.1 AwEA...
SVCB: 1 target.example.com. alpn=h2
HTTPS: 1 . alpn=h3,h2 ipv4hint=192.0.2.1
TLSA: 3 1 1 aabbccdd...
SSHFP: 1 2 aabbccdd...
OPENPGPKEY: AwEA...
DNSSEC algorithm identifiers now follow the numeric values defined in RFC 4034. For example, RSASHA256 becomes 8, ECDSAP256SHA256 becomes 13, and ED25519 becomes 15. The DS digest type also changes, with SHA-256 becoming 2.
Before: RRSIG: A RSASHA256 2 300 ...
After: RRSIG: A 8 2 300 ...
Before: DS: 12345 RSASHA256 SHA-256 aabb...
After: DS: 12345 8 2 aabb...
Before: DNSKEY: 257 3 RSASHA256 AwEA...
After: DNSKEY: 257 3 8 AwEA...
HINFO character-strings also change to being individually quoted.
If you need a format that absolutely won't shift under you, the post recommends using DoH wireformat (the binary format) instead of the JSON API — since the JSON format has no formal RFC to begin with, further changes remain possible down the line.
Wrap-up
- 1.1.1.1's DoH JSON API now returns several record types — CAA, TLSA, SVCB, HTTPS, and more — in a human-readable format
- DNSSEC-related records switch their algorithm field from mnemonic names to RFC 4034 numeric identifiers
- Old and new formats may both appear during the rollout, so watch out for that
- If you need a stable format, use DoH wireformat instead
- If you're parsing 1.1.1.1's DoH JSON API in a client or tool, now's a good time to double-check your parsing logic.