Diagnostic DNSSEC
Missing DS record breaks DNSSEC validation
You turned on DNSSEC at your DNS host. It is signing every answer. Then some resolvers stop returning your site at all, and instead just say SERVFAIL. Nothing is wrong with the signatures themselves. The missing piece sits one level up, at the registrar, where a small record called the DS record was supposed to be published and never was. Here is why that breaks everything and the exact steps to fix it.
The zone is signed at the DNS host, which means it has DNSKEY and RRSIG records and answers are cryptographically signed. But the DS record that tells the parent zone (the registry) "trust this key" was never published at the registrar. Without that DS record, a validating resolver cannot build a chain of trust from the root down to your zone, treats the signatures as unverifiable, and returns SERVFAIL instead of your answer. The fix is to copy the DS parameters (Key Tag, Algorithm, Digest Type, Digest) from the DNS host and enter them in the registrar's DNSSEC settings so the registrar can submit the DS record to the registry.
The problem in plain words
DNSSEC works like a chain of trust that runs from the root of the internet, down to the registry for your top level domain, down to your registrar, down to your zone. Each link in that chain has to point at the next one. Your DNS host signs its own answers with a key. But something else has to vouch for that key by publishing a record that says, in effect, "here is the fingerprint of the key this zone uses to sign its records, trust it." That vouching record is the DS record, and it does not live at your DNS host. It lives one level up, in the parent zone, which is controlled by the registry and set through your registrar.
If the DNS host is signing but the DS record was never sent to the registrar, the chain has a broken link right in the middle. A resolver that does not check DNSSEC at all will not notice, because it just takes whatever answer it gets. A resolver that does check DNSSEC will see a signed answer, look for the DS record to confirm the signature is trustworthy, find nothing there, and refuse to trust the answer at all. It returns SERVFAIL rather than risk serving an answer it cannot verify.
Why it happens
This is described directly in the DNSSEC protocol documents: a DS record in the parent zone is what lets a validating resolver trust the child zone's key, and without it the chain cannot be built. A few common ways a zone ends up signed with no DS published:
- DNSSEC was enabled at the DNS host, which generates keys and starts signing right away, but the separate step of copying the DS parameters into the registrar was skipped or forgotten.
- The DNS host and the registrar are different companies, so enabling DNSSEC in one place does nothing automatically in the other. Someone has to manually carry the DS values across.
- The zone's signing key was rotated (a new Key Tag or Digest) but the old DS record was left in place or removed, and the new one was never re-submitted at the registrar.
- A registrar transfer or nameserver change happened and the DS record was dropped in the process, while the DNS host kept signing as if nothing changed.
Whatever the cause, the result looks the same from the outside: the zone answers fine for anyone not checking DNSSEC, and fails outright for anyone who is.
Signing a zone and publishing the DS record are two separate actions in two separate places, done by two different parties. The DNS host can sign all day, but only the registrar can push the DS record to the registry. If either half is missing, DNSSEC is not "half working," it is fully broken for anyone who validates.
The fix, as a flow
Confirm the zone really is signed, confirm the DS record really is missing at the parent, then copy the exact DS parameters from the DNS host into the registrar's DNSSEC section so the registrar can submit them to the registry.
How to fix it
Confirm the zone is actually signed at the DNS host
Query the DNSKEY record for the zone against a public resolver or the authoritative nameservers. If DNSSEC is on, you should get back one or more DNSKEY lines. If this comes back empty, the problem is different, the zone is not signed at all yet.
dig +short DNSKEY example.com @8.8.8.8
Check whether the DS record exists at the parent registry
A DS query against a recursive resolver, and a trace that shows the referral from the TLD servers directly, will reveal whether the registry has a DS record on file for this zone at all. An empty answer here, combined with DNSKEY records present in step 1, is the exact signature of this problem.
dig +short DS example.com
dig +trace DS example.com
Reproduce the validation failure directly
Query a validating resolver like 1.1.1.1 with DNSSEC turned on. It should return SERVFAIL. Then run the same query with checking disabled. If that comes back with a normal answer, the zone itself is fine and the problem is only the missing chain of trust.
# Validating query, expect SERVFAIL
dig +dnssec example.com @1.1.1.1
# Same query, checking disabled, expect a normal answer
dig +cd +dnssec example.com @1.1.1.1
Enable DNSSEC at the DNS host and copy the DS parameters
In the DNS host's dashboard, find the DNSSEC section for the domain and turn it on if it is not already. This generates the key material and shows the exact DS parameters: Key Tag, Algorithm, Digest Type, and Digest. For example, on Cloudflare the default algorithm is 13 (ECDSA P-256 SHA-256) and digest type is 2 (SHA-256).
Key Tag: 2371
Algorithm: 13 (ECDSA P-256 SHA-256)
Digest Type: 2 (SHA-256)
Digest: 1F1123DA6B9C5E4A2B...
Enter the DS record at the registrar
Log in to the registrar where the domain is actually registered, which may or may not be the same company as the DNS host. Find the DNSSEC or DS Records section under the domain's settings, and enter the exact Key Tag, Algorithm, Digest Type, and Digest copied from the DNS host in step 4. Save the record.
Let the registrar push it to the registry
Once saved, the registrar submits the DS record to the TLD registry through EPP. If the registrar and the DNS host are the same provider, this step usually happens automatically the moment DNSSEC is turned on, and there is nothing further to copy by hand.
If you need to stop the breakage right away, disable DNSSEC at the DNS host
Turning DNSSEC off at the DNS host stops the zone from signing at all, which removes the mismatch and restores normal answers immediately. This is a temporary rollback to buy time, not the real fix, since the goal is a signed zone with a matching DS record, not an unsigned zone.
How to check it worked
Re-run the DS lookup against a public resolver and confirm it now returns a record matching the Key Tag, Algorithm, and Digest shown at the DNS host. Then re-run the validating query and confirm the answer comes back normally with the Authenticated Data flag set.
# 1. Confirm the DS record is now published at the registry
dig +short DS example.com
# 2. Confirm the values match what the DNS host showed you
dig +trace DS example.com
# 3. Confirm validation now passes, look for the "ad" flag in the header
dig +dnssec example.com @1.1.1.1
# 4. Cross-check with an online DNSSEC analyzer
# https://dnsviz.net/d/example.com/dnssec/
A good result looks like this: the DS query returns a record whose Key Tag, Algorithm, and Digest match the DNS host exactly. The validating query against 1.1.1.1 or 8.8.8.8 returns a normal answer with the ad (Authenticated Data) flag set in the header, and no SERVFAIL for any record type in the zone. On dnsviz.net or Verisign's DNSSEC Debugger, the chain of trust from the root down to the zone should show as fully valid with no missing DS and no broken links. If any of these still show gaps, double check that the Key Tag and Digest you entered at the registrar match the current key at the DNS host, since a rotated key with a stale DS value produces the exact same SERVFAIL symptom.
Case studies
The domain registered in one place, hosted in another
A team registered their domain at one registrar years ago, then moved DNS hosting to Cloudflare later. They enabled DNSSEC in Cloudflare, saw the signing indicator turn green, and assumed they were done. Two weeks later a partner using a validating resolver reported the site was completely unreachable while everyone else saw it fine.
The DNSKEY was present but the DS record had never been sent to the original registrar, since enabling DNSSEC at Cloudflare has no way to reach a separate registrar automatically. Once the DS parameters were copied into the registrar's DNSSEC page, the SERVFAIL cleared within the hour.
The rotation that left a stale DS behind
A security review recommended rotating the DNSSEC signing key. The DNS host generated a new key and started signing with it, but the old DS record, matching the old Key Tag, was still sitting at the registrar. Now the digest at the registry no longer matched anything the zone was actually signing with.
The fix looked identical to a fully missing DS from the outside, SERVFAIL on validating resolvers only, but the underlying issue was a mismatch rather than an absence. Removing the stale DS and submitting the new one at the registrar restored the chain.
A healthy signed zone always has a DS record at the registry that matches the current DNSKEY at the DNS host. When that match is in place, validating resolvers return the ad flag and normal answers, and non-validating resolvers see no difference at all. Check this any time you rotate keys, switch DNS hosts, or move registrars, since any of those three changes can quietly break the link between the signature and the record that vouches for it.
FAQ
Why does my signed domain return SERVFAIL instead of an answer?
Your DNS host turned on DNSSEC and is signing responses, but the DS record for that signature was never published at the registrar. A validating resolver sees signed records with no way to confirm they are trustworthy, and returns SERVFAIL instead of guessing. Publishing the DS record at the registrar closes the gap.
How do I know if this is a DS problem and not something else?
Run dig +dnssec on the domain against a validating resolver like 1.1.1.1. If it returns SERVFAIL, but the same query with +cd (checking disabled) returns a normal answer, the zone is signed correctly and only the chain of trust is broken. Confirm with a DS lookup at the registry, which will come back empty.
Can I fix a missing DS record through my DNS host's API?
No. The DNS host can generate the signing keys and show you the DS parameters, but the DS record itself lives in the parent zone at the registry, and only the registrar can submit it there through EPP. You have to add it in the registrar's DNSSEC settings, not the DNS host's API.
Related field notes
Citations
On the problem:
- RFC 4035: Protocol Modifications for the DNS Security Extensions. datatracker.ietf.org/doc/html/rfc4035
- RFC 3658: Delegation Signer (DS) Resource Record (RR). datatracker.ietf.org/doc/html/rfc3658
- Cloudflare DNS docs: Troubleshooting DNSSEC. developers.cloudflare.com/dns/dnssec/troubleshooting
On the solution:
- Cloudflare DNS docs: DNSSEC. developers.cloudflare.com/dns/dnssec
- Cloudflare Registrar docs: Domain Name System Security Extensions (DNSSEC). developers.cloudflare.com/registrar/get-started/enable-dnssec
- AWS re:Post: Troubleshoot DNS SERVFAIL responses in Route 53. repost.aws/knowledge-center/route53-dns-servfail-response
Stuck on a tricky one?
If you have a DNS, delegation, or domain security problem you would rather hand off, this is the kind of work I do. Message me and we can work through it together.
Did this fix your DNSSEC validation?
If this helped clear a SERVFAIL you were chasing, you can buy me a coffee. It is the best way to keep these field notes free and growing.
Buy me a coffee on Ko-fi