Diagnostic DNSSEC

Orphaned DS record left after disabling DNSSEC

Someone turned DNSSEC off. The zone stopped signing. And now the whole domain is down for anyone using a resolver that checks DNSSEC, like Google's 8.8.8.8 or Cloudflare's 1.1.1.1. Nothing about the zone itself is broken. The leftover piece is one small record still sitting at the registrar, one level above the zone, still telling the world "this domain is signed." Here is why that one forgotten record takes down the whole domain, and the safe order to clean it up.

dig + DNSSEC Registrar action, not DNS host Diagnostic only
A padlock on a keyboard
Photo by FlyD on Unsplash
The short answer

DNSSEC has two halves that live in two different places. The signing (DNSKEY and RRSIG) lives in the zone at the DNS host. The trust anchor, called the DS record, lives one level up at the registrar and registry. When someone disables DNSSEC by turning off signing at the DNS host but does not also delete the DS record at the registrar, the parent zone keeps asserting "this domain is signed with key X" while the zone itself no longer publishes that key or any signatures. A validating resolver sees the DS, finds no matching DNSKEY or RRSIG, cannot build a chain of trust, and treats the whole domain as broken, so it SERVFAILs. The fix is to delete the DS record at the registrar, in that order and after signing is confirmed off, then wait for the old DS TTL to expire.

The problem in plain words

DNSSEC is really two jobs split across two different owners. The DNS host does the signing: it publishes a DNSKEY record and signs every answer with an RRSIG. The registrar does the vouching: it publishes a DS record at the registry, one level above the zone, that says "here is the fingerprint of the key this zone signs with, trust it." Those two records are supposed to move together. In practice they often do not, because they live in two different dashboards owned by two different companies.

Disabling DNSSEC is usually a one click action at the DNS host. Click it, and the zone stops publishing DNSKEY and RRSIG right away. But that click does nothing to the registrar. The DS record just sits there in the parent zone, unaware that the key it points to is gone. A resolver that does not check DNSSEC never asks about the DS record and never notices. A resolver that does check DNSSEC follows the normal steps: see the DS at the parent, go fetch the matching DNSKEY and RRSIG from the zone, find nothing, and refuse to trust any answer from that zone at all. The result is not a partial failure. It is a full SERVFAIL for every record type in the domain, for every person using a validating resolver.

DS still at registry "trust key X" never removed No DNSKEY / RRSIG signing was turned off Key X does not match anything Validating resolver: SERVFAIL the fix lives at the registrar
The zone stopped signing, which is fine on its own. The orphaned DS record left behind at the registry is what turns that into a full domain outage for validating resolvers.

Why it happens

The DNSSEC protocol documents are direct about this: the DS record is what a validating resolver relies on to confirm a zone's signing key, and a DS with no matching DNSKEY or RRSIG is treated as Bogus, not simply Insecure. A few common ways a domain ends up with an orphaned DS:

Whatever the cause, the outside symptom looks identical every time: the domain answers fine for anyone not validating DNSSEC, and SERVFAILs completely for anyone who is, right after someone thought they had turned DNSSEC off cleanly.

The key insight

Turning off signing and removing the DS record are two separate actions in two separate places, owned by two different parties. Stopping the zone from signing is not the same as disabling DNSSEC end to end. Until the DS record at the registrar is gone too, the domain is not unsigned, it is broken, because the parent zone is still vouching for a key that no longer exists.

The fix, as a flow

Confirm the DS record is really still there at the registry, confirm the zone truly stopped signing, then remove the DS record at the registrar and wait out its TTL before treating the domain as fully unsigned.

Confirm DS still present at registry Confirm DNSKEY / RRSIG are gone Delete DS record at the registrar Wait out the old DS TTL Domain is cleanly Insecure no more SERVFAIL
Nothing needs to change again at the DNS host, since signing is already off. The missing action happens entirely at the registrar, which is the only party able to remove the DS record from the parent zone.

How to fix it

1

Confirm a DS record is still published at the parent

Query the DS record for the domain against a public resolver, or query the TLD servers directly. A non-empty result means a DS record is still sitting at the registry, which is the first half of the problem.

Terminal
check-ds.sh
dig DS example.com +short

dig DS example.com @a.gtld-servers.net
2

Confirm the zone itself stopped signing

Query the DNSKEY and RRSIG records directly at the zone. If DNSSEC was really turned off, both of these should come back empty. Empty DNSKEY and RRSIG next to a non-empty DS is the exact signature of an orphaned DS record.

Terminal
check-signing.sh
dig DNSKEY example.com +short

dig RRSIG example.com +short

dig SOA example.com +dnssec
3

Reproduce the validation failure directly

Query the domain normally, with validation on. It should come back SERVFAIL with no answer. Then run the same query with checking disabled. If that comes back with a normal NOERROR answer, the record itself is fine and DNSSEC validation is the only thing breaking resolution.

Terminal
reproduce.sh
# Normal query, validation on, expect SERVFAIL
dig example.com A

# Same query, checking disabled, expect a normal NOERROR answer
dig example.com A +cd
4

Trace the delegation to see the mismatch in one shot

A full trace with DNSSEC flags shows the parent zone still handing back a DS record at the delegation step, with no matching DNSKEY or RRSIG served by the domain's own authoritative nameservers.

Terminal
trace.sh
dig +trace +dnssec example.com
5

Remove the DS record at the registrar, not the DNS host

Log in to the domain's registrar, whether that is Namecheap, GoDaddy, Google Domains or Squarespace, or the registrar tab in your registry if the registrar and DNS host differ. Find the DNSSEC or DS Records section under the domain and delete the DS entry for it. It typically shows the same Key Tag, Algorithm, Digest Type, and Digest that were published when DNSSEC was turned on.

DNS record
example.com DS record to delete (as shown at the registrar)
Key Tag:      2371
Algorithm:    13 (ECDSA P-256 SHA-256)
Digest Type:  2 (SHA-256)
Digest:       a1b2c3...
6

If the DNS host is Cloudflare, finish disabling DNSSEC there only after the registrar side is clear

Confirm the registrar-side DS record is removed first. Then complete disabling DNSSEC in the DNS host's dashboard, for example under DNS, Settings, DNSSEC, Disable, or through its API. Cloudflare's own guidance is to keep zone signing live until the parent's DS TTL has expired, so the two sides go dark in the safe order instead of at the same time.

Terminal
disable-cloudflare-dnssec.sh
curl -X DELETE "https://api.cloudflare.com/client/v4/zones/{zone_id}/dnssec" \
  -H "Authorization: Bearer {api_token}" \
  -H "Content-Type: application/json"
7

If there is no delete option in the registrar UI, open a support ticket

Some registrars do not expose a self-service DS delete button. If that is the case, open a support ticket asking them to remove the DS record for the domain. This is the required manual step and it cannot be done through the Cloudflare zone DNS API, since the DS record lives at the registry, not in Cloudflare's own zone.

8

Wait for the DS TTL to expire before calling the zone fully unsigned

DS removal is not instant everywhere at once. Wait for the DS record's TTL to expire, commonly one to two days, and Cloudflare recommends waiting roughly one and a half times the DS TTL. TLD level propagation can take up to 48 hours in total. Only after that window treat the domain as cleanly unsigned.

How to check it worked

After the registrar confirms the DS is removed and the TTL window has passed, re-run the same checks from the start and confirm every one of them now agrees with a plain, unsigned answer.

Terminal
verify.sh
# 1. DS at the parent should now be empty
dig DS example.com +short

# 2. Normal query should return a normal NOERROR answer with the expected IP
dig example.com A

# 3. No "ad" flag, no attempted validation, just a clean Insecure zone
dig example.com +dnssec

# 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 nothing at all. The plain A query returns a normal NOERROR answer with the expected IP, matching what the +cd query already showed earlier. There is no Authenticated Data flag anywhere, because there is nothing left to authenticate, and no SERVFAIL for any record type. On dnsviz.net or a similar DNSSEC debugger, the domain should show no DS at the parent and no broken chain, just a clean, consistently Insecure zone. If SERVFAIL is still showing up anywhere, the DS TTL window has probably not fully expired yet, or a secondary registrar or reseller layer still has a cached copy of the old record.

Case studies

Same day rollback

The domain that broke an hour after "fixing" a key rotation

A team hit a DNSSEC key rotation problem and decided the fastest fix was to just turn DNSSEC off entirely. They disabled signing at the DNS host and moved on. An hour later, a partner using Google's 8.8.8.8 reported the whole site was down, while the team's own machines, using a non-validating resolver, saw nothing wrong at all.

A DS lookup at the registry still returned the old key. The DNS host's own DNSKEY and RRSIG were already gone. Deleting the DS record at the registrar and waiting about a day and a half cleared the SERVFAIL for everyone using a validating resolver.

Split provider setup

The registrar nobody remembered to log back into

A domain was registered at one company years earlier, then moved to a different DNS host for day to day management. Disabling DNSSEC in the DNS host's dashboard felt complete, since the signing toggle turned grey immediately. Nobody thought to check the original registrar, which still had the DS record from when DNSSEC was first enabled.

The domain SERVFAILed for any validating resolver for close to a week before support noticed the pattern. Logging back into the original registrar and deleting the leftover DS record fixed it within the TTL window.

What good looks like

A cleanly disabled DNSSEC domain has no DS record at the registry and no DNSKEY or RRSIG at the zone, and both went dark in that order with the DS TTL respected in between. Validating resolvers see a plain Insecure zone and a normal answer every time, with no Authenticated Data flag and no SERVFAIL. Whenever DNSSEC is turned off anywhere, check the registrar's DS record as its own separate step, not as something the DNS host's toggle handles for you.

FAQ

Why did my domain break right after I turned off DNSSEC?

Turning off DNSSEC at your DNS host stops it from signing the zone, but the DS record at the registrar is a separate record in the parent zone. If nobody deletes it, the registry keeps pointing at a key that no longer exists. A validating resolver sees the DS, finds no matching signature, and returns SERVFAIL for the whole domain.

How do I know this is an orphaned DS and not something else?

Check DS at the parent and DNSKEY at the zone at the same time. If dig DS returns a record but dig DNSKEY and dig RRSIG both come back empty, that mismatch is the orphaned DS. Confirming with dig +cd, which disables validation, coming back with a normal answer while the plain query SERVFAILs seals it.

Can I remove the orphaned DS record through my DNS host's API?

No. The DS record lives in the parent zone at the registry, not in your DNS host's zone file, so a DNS host API like Cloudflare's cannot delete it. You have to remove it in the registrar's DNSSEC settings, or open a support ticket with the registrar if there is no self-service option.

Related field notes

Citations

On the problem:

  1. RFC 4035: Protocol Modifications for the DNS Security Extensions. datatracker.ietf.org/doc/html/rfc4035
  2. RFC 4034: Resource Records for the DNS Security Extensions. rfc-editor.org/rfc/rfc4034
  3. Cloudflare DNS docs: Troubleshooting DNSSEC. developers.cloudflare.com/dns/dnssec/troubleshooting

On the solution:

  1. AWS Route 53 Developer Guide: Disabling DNSSEC signing. docs.aws.amazon.com/Route53/latest/DeveloperGuide/dns-configuring-dnssec-disable.html
  2. DNSimple Help: Manage DS Records When Changing DNS. support.dnsimple.com/articles/ds-records-changing-dns
  3. Cloudflare API docs: DNS, DNSSEC, Delete DNSSEC Records. developers.cloudflare.com/api/resources/dns/subresources/dnssec/methods/delete

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.

Contact me on LinkedIn

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

Back to all DNS and Domains field notes