Support Library
Debugging DNSSEC validation errors
Debug DNSSEC validation errors step by step: confirm validation is the cause, compare DS with DNSKEY, check signatures, and fix the broken link.
The short answer
A DNSSEC validation error shows up as SERVFAIL from validating resolvers while resolvers that do not validate keep answering. To debug it, first confirm that validation is the cause, then walk the chain of trust from the parent's DS record to the zone's keys and signatures until you find the link that does not hold.
Use one validating resolver for every test, so the results are comparable:
$ dig @1.1.1.1 example.com A +dnssec
$ dig @1.1.1.1 example.com A +dnssec +cdflag
$ delv example.com A
$ dig @1.1.1.1 example.com DNSKEY +dnssec
Step 1: confirm it is validation
| Result | What it suggests |
|---|---|
| Normal query: answer with the ad flag | The resolver validated the answer. DNSSEC is working from this resolver's point of view. |
| Normal query: answer without ad | The zone is probably unsigned (no DS at the parent), or the resolver does not validate. Not, on its own, a sign of breakage. |
| Normal query: SERVFAIL; +cdflag: answer | Strong evidence of a validation failure. Continue with step 2. |
| SERVFAIL both ways | Probably not DNSSEC. Check the name servers and delegation; see DNS SERVFAIL Explained. |
Remember what the tools do. +dnssec only asks for signatures, and +trace only follows referrals; neither validates. The AD flag is the resolver's assertion that it validated. delv does its own validation from the root trust anchor and prints either ; fully validated or the reason it failed, and an Extended DNS Error from the resolver often names the problem directly, for example EDE 9 (DNSKEY Missing) or EDE 7 (Signature Expired).
Step 2: compare the DS with the DNSKEY set
Get the DS records from the parent zone and the DNSKEY records from the zone itself:
$ dig +norecurse @a.gtld-servers.net example.com DS +noall +answer
example.com. 86400 IN DS 12345 13 2 8E7C2BA8A5F995FE...
$ dig @1.1.1.1 example.com DNSKEY +cdflag +multiline +noall +answer
example.com. 3600 IN DNSKEY 257 3 13 ( EiMPGdn052xY... ) ; KSK; alg = ECDSAP256SHA256 ; key id = 12345
example.com. 3600 IN DNSKEY 256 3 13 ( HObHih1ug+ea... ) ; ZSK; alg = ECDSAP256SHA256 ; key id = 40001
Ask a server of your own TLD for the DS; for .com and .net that is one of the gtld-servers.net hosts. +cdflag on the DNSKEY query lets you see the keys even when the resolver considers them bogus, and +multiline makes dig print each key's tag.
At least one DS must match a published key. A matching key tag is the first check, but tags can collide, so the algorithm number must match too, and the digest must be the hash of that exact key. If you have the BIND tools, dnssec-dsfromkey computes the DS a key should have, which you can compare with the parent's.
Step 3: check the signatures
$ dig @1.1.1.1 example.com A +dnssec +cdflag +multiline +noall +answer
Each RRSIG in the answer shows the algorithm, the key tag that made it, and two timestamps: when the signature expires and when it became valid. Check that the key tag belongs to a key in the DNSKEY set, that the expiry is in the future, and that the start time is not in the future. Do the same for the DNSKEY set itself, which must be signed by the key that the DS points to.
What you are likely to find
| Finding | Typical cause | Fix |
|---|---|---|
| DS matches no published key | A KSK rollover or provider move left the old DS at the registrar | Publish the correct DS, or remove the stale one, at the registrar |
| DS present, zone unsigned | Signing was turned off, or the zone moved to a provider that does not sign, without removing the DS | Remove the DS, or turn signing back on with the matching key |
| Expired signatures | The signer stopped re-signing, or a secondary stopped transferring updates | Fix the signer or transfer, then re-sign |
| Signatures not valid yet | The signing server's clock is ahead | Correct the clock and re-sign |
| Some name servers serve different keys | A secondary still has an old copy of the zone | Check each server's SOA serial and force a transfer |
After the fix, caches still hold the old records until their TTLs run out. A DS change is limited by the parent's DS TTL, often a day for gTLDs, so plan for validating resolvers to recover gradually rather than at once.
How DNS Panopticon helps
Domain Visualizer requests DS and DNSKEY records through a public resolver and checks whether the resolver set the AD flag. It reports DNSSEC as absent, validating, DS present without DNSKEY, DNSKEY without DS, or signed but not validating, which tells you which of the cases above to investigate. It does not compare key tags, read signature dates or query each name server separately, so use the steps above, delv or DNSViz for that detail.
Sources and further reading
- RFC 4033: DNS Security Introduction and Requirements
- RFC 4035: Protocol Modifications for the DNS Security Extensions: section 5 describes how resolvers authenticate answers
- RFC 6781: DNSSEC Operational Practices, Version 2
- RFC 8914: Extended DNS Errors
- ISC: BIND 9 manual pages for dig, delv and dnssec-dsfromkey
- DNSViz: a visual check of a domain's DNSSEC chain