The Problem DNSSEC Solves
Plain DNS has no way to prove an answer is genuine. When your resolver asks "what is the IP address of example.com?", it accepts the first reply that matches the question. An attacker who can get a forged reply in first — or who controls a network the query passes through — can send you to a server of their choice. This is cache poisoning, and in 2008 Dan Kaminsky showed it could be done against most resolvers on the internet in seconds.
Resolvers were patched to make forgery harder (random source ports, random query IDs), but those patches only raise the cost; they don't prove anything. DNSSEC (DNS Security Extensions) adds cryptographic signatures to DNS records so a validating resolver can check that an answer really came from the zone's owner and wasn't altered on the way.
Two things DNSSEC doesn't do are worth stating up front:
- It doesn't encrypt anything. Queries and answers are still readable on the network. Encryption is the job of DNS-over-HTTPS (DoH) and DNS-over-TLS (DoT).
- It doesn't protect the last hop by default. Your laptop usually trusts the resolver's word that validation passed. DNSSEC protects the path between the resolver and the authoritative servers.
The Three Records That Make It Work
RRSIG — a signature over a set of records. Every signed record set (all the A records for a name, all the MX records, and so on) has an RRSIG next to it, with an inception and expiry time:
$ dig +dnssec example.com A
;; flags: qr rd ra ad; QUERY: 1, ANSWER: 3, AUTHORITY: 0, ADDITIONAL: 1
example.com. 188 IN RRSIG A 13 2 300 20261021152807 20261019132807 34505 example.com. upzpCn5L...The 13 is the algorithm (ECDSA P-256 with SHA-256), 34505 is the tag of the key that made the signature, and the two timestamps say the signature is valid from 19 to 21 October 2026. Signatures expire, which is why DNSSEC zones must be re-signed continuously.
DNSKEY — the zone's public keys, published in the zone itself. There are usually two kinds:
$ dig cloudflare.com DNSKEY +short
256 3 13 oJMRESz5E4gYzS/q6XDrvU1qMPYIjCWzJaOau8XNEZeqCYKD5ar...
257 3 13 mdsswUyr3DPW132mOi8V9xESWE8jTo0dxCjjnopKl+GqJxpVXck...Flag 257 marks the key-signing key (KSK), which signs only the DNSKEY set. Flag 256 marks the zone-signing key (ZSK), which signs everything else. Splitting them means the ZSK can be rotated often without involving the parent zone.
DS (Delegation Signer) — a hash of the KSK, published in the parent zone. For cloudflare.com it lives in .com:
$ dig cloudflare.com DS +short
2371 13 2 32996839A6D808AFE3EB4A795A0E6A7A39A76FC52FF228B22B76F6D6 3826F2B9Key tag 2371, algorithm 13, digest type 2 (SHA-256), then the hash. The DS record is what links your zone into the chain of trust.
The Chain of Trust
A validating resolver ships with one trusted key: the root zone's KSK. From there it walks down:
- The root's DNSKEY is trusted because it matches the built-in trust anchor.
- The root publishes a DS record for
.com, signed by the root's key. That DS vouches for.com's KSK. .compublishes a DS record forcloudflare.com, signed by.com's key. That DS vouches forcloudflare.com's KSK.cloudflare.com's KSK signs its DNSKEY set, its ZSK signs the A record, and the resolver checks that RRSIG.
If every link checks out, the answer is secure and the resolver sets the AD (Authenticated Data) flag — visible as ad in the dig output above. If any link fails, the resolver doesn't return a possibly forged answer: it returns SERVFAIL.
This is why the DS record matters so much. A zone can be perfectly signed, but without a DS in the parent nothing connects it to the root, and resolvers treat it as unsigned. That is called an island of security.
Checking a Domain Yourself
Three dig queries tell you almost everything.
Is there a DS record in the parent?
$ dig google.com DS +short
$Empty: google.com is not DNSSEC-signed. That's common — most large domains, including Google and Amazon, don't sign their main zone. DNSSEC adoption among .com domains is still in the single-digit percentages.
Does the zone publish DNSKEYs? dig example.com DNSKEY +short — you want at least one 257 key.
Does a validating resolver mark the answer as authenticated?
$ dig @1.1.1.1 cloudflare.com A | grep flags:
;; flags: qr rd ra ad; QUERY: 1, ANSWER: 2, AUTHORITY: 0, ADDITIONAL: 1The ad flag means Cloudflare's resolver validated the whole chain. The DNSSEC Checker runs these queries for you and sorts the result into five states:
| State | DS in parent | DNSKEY in zone | Validates | Meaning |
|---|---|---|---|---|
| Secure | Yes | Yes | Yes | Fully signed and anchored |
| Unsigned | No | No | — | No DNSSEC; answers aren't authenticated but resolve normally |
| Island | No | Yes | No | Signed but not anchored; resolvers treat it as unsigned |
| Broken | Yes | No | No | Parent promises signatures that don't exist; lookups fail |
| Bogus | Yes | Yes | No | Signatures invalid or expired; lookups fail |
"Unsigned" is not an error. "Broken" and "bogus" are outages for everyone using a validating resolver.
What a Validation Failure Looks Like
dnssec-failed.org is a domain deliberately published with broken signatures so people can test their resolvers:
$ dig @1.1.1.1 dnssec-failed.org A
;; ->>HEADER<<- opcode: QUERY, status: SERVFAILNow repeat it with the +cd (checking disabled) flag, which asks the resolver to skip validation:
$ dig @1.1.1.1 +cd dnssec-failed.org A +short
96.99.227.255The record exists, but the resolver refuses to hand it out because the signatures don't verify. SERVFAIL that disappears with `+cd` is the signature of a DNSSEC problem. It's the first thing to try when a domain resolves for some users and not others: Google Public DNS, Cloudflare 1.1.1.1, Quad9 and most ISP resolvers validate, while some corporate resolvers don't.
DNSViz (dnsviz.net) draws the entire chain as a diagram and highlights the broken link, which is the fastest way to see exactly where it fails.
The Mistakes That Break DNSSEC
Changing DNS provider without removing the DS record. This is the most common DNSSEC outage. The old provider signed the zone; the DS record at the registrar points to the old provider's key; the new provider doesn't sign the zone, or signs it with a different key. The parent now vouches for a key that no longer exists, and the domain goes dark for every validating resolver. The safe order is: remove the DS at the registrar, wait at least the DS record's TTL (often 24–48 hours), move providers, then re-enable DNSSEC with the new provider's DS.
Expired signatures. RRSIGs have expiry dates. If automatic re-signing stops — a cron job dies, a hidden primary goes offline — the zone works until the signatures run out and then fails all at once.
KSK rollover without updating the DS. Rotating the key-signing key requires publishing the new DS in the parent before the old key is removed. Managed DNS providers automate this; self-hosted setups often don't.
Outdated algorithms. RSA/SHA-1 (algorithms 5 and 7) and SHA-1 DS digests (digest type 1) are deprecated. The DNSSEC Checker warns about both. ECDSA P-256 (algorithm 13) is the common modern choice — compact signatures and widely supported.
If you use a managed DNS provider, enabling DNSSEC is usually a single switch plus pasting a DS record into your registrar's control panel. Most outages come from changing something later without remembering that DNSSEC is on.
