Bali, Indonesia
Insights

Moved to Cloudflare Nameservers and Got SERVFAIL From a Stale DS Record

October 27, 2026
0:00
You moved a domain's nameservers to Cloudflare. The records in the dashboard look right, and the site loads on your machine. Then reports start coming in. Some visitors get a DNS error, and dig against a public resolver returns SERVFAIL. The zone itself is fine. The problem is one level up, at the registry, where a DS record still points at DNSSEC keys that only the old provider ever had. This article is written as a post-mortem of how this kind of incident usually unfolds. It covers the impact, the investigation, the point where the cause becomes clear, the quick mitigation, and the change in process that stops it from happening again. If you only want the fix, skip to the last two sections.
The confusing part of this failure is that it is partial. Whether a visitor can reach the domain depends on which resolver answers their DNS queries, not on where they are. DNSSEC adds signatures to DNS records. A validating resolver checks those signatures before it returns an answer. Many large public resolvers validate by default. Many ISP resolvers and office networks do not. A non-validating resolver asks Cloudflare's nameservers, gets a valid A record, and the site loads. A validating resolver sees that the parent zone says this domain is signed, finds no matching signature, and treats the answer as forged. It returns SERVFAIL rather than an answer it cannot trust. The result is reports that look contradictory. The site works on mobile data but not on home Wi-Fi. It works for one colleague and fails for another. Email is affected too. A sending server that uses a validating resolver cannot look up your MX record, so incoming mail gets deferred instead of delivered. From the support side, a site that works for some people and fails for others right after a nameserver change usually gets blamed on propagation. That explanation is wrong here, and waiting longer will not fix it.
The first checks usually come back clean, which is why this incident can drag on. The records in the Cloudflare dashboard are correct. Querying Cloudflare's assigned nameservers directly returns the right A and MX records. The registrar shows the new nameservers. Every check aimed at the zone itself passes. The test that settles it is asking a validating resolver the same question twice: once normally and once with validation turned off. The +cd flag sets the Checking Disabled bit, which tells the resolver to return the data without DNSSEC validation. The +dnssec flag requests DNSSEC records in the response, so you can see whether signatures are present.
BASH
# Normal query through a validating resolver
dig example.com A @1.1.1.1 +dnssec

# Same query with validation disabled
dig example.com A @1.1.1.1 +dnssec +cd
If the first query returns status: SERVFAIL and the second returns status: NOERROR with the correct IP, the records are fine and validation is the problem. A recent dig talking to a resolver that supports Extended DNS Errors may also print an EDE line. DNSKEY Missing or DNSSEC Bogus there points straight at a broken chain of trust. If your dig or resolver does not show EDE, the +cd comparison tells you the same thing. If you query a non-validating resolver, both requests succeed. That is why testing from only your own network can make everything look healthy.
DNSSEC works as a chain of trust. The root zone vouches for the TLD, for example .com. The TLD vouches for your domain through a DS (Delegation Signer) record. A DS record holds a hash of your zone's key-signing key, the DNSKEY record with flag 257. The DS lives in the parent zone, not in your zone. You publish it through your registrar, and the registry serves it. When the old provider signed your zone, its key went into a DS record at the registry. Changing the nameservers did not change that DS. Many registrars leave existing DS records alone when nameservers change. So the parent still tells resolvers that this domain is signed with a specific key. Cloudflare's nameservers either serve no DNSKEY at all, because DNSSEC is not enabled there yet, or serve a different key that does not match. In both cases validation fails. To confirm this, compare what the parent publishes with what the new nameservers serve:
BASH
# Find the TLD's nameservers, then ask one directly for your DS record
dig com NS +short
dig example.com DS @a.gtld-servers.net +norecurse

# Ask your assigned Cloudflare nameserver for the zone's keys
dig example.com DNSKEY @your-assigned-name.ns.cloudflare.com +dnssec +multi
Replace com and the gtld-servers.net host with the values for your own TLD, and use the nameserver names Cloudflare assigned to your zone.
TEXT
; Illustrative output format: DS record still published at the parent
example.com.   86400   IN   DS   12345 8 2 <hex digest from the old provider>

; Illustrative output format: DNSKEY query to the new nameserver
;; ANSWER SECTION is empty, or contains a key with a different key id and algorithm
The DS record has four fields: key tag, algorithm, digest type, and digest. With +multi, dig prints each DNSKEY with a comment showing its key id and algorithm. If the DS key tag does not match any key id that Cloudflare serves, or no DNSKEY comes back at all, you have found the cause.
The fastest way to restore resolution is to delete the old DS record at the registrar. With no DS at the parent, resolvers treat the domain as unsigned (insecure), accept unsigned answers, and resolve it normally. This means the domain runs without DNSSEC protection for a while. That is usually an acceptable trade-off against a domain that validating resolvers cannot resolve at all. Be clear about the choice when you make it, and plan to turn DNSSEC back on. Recovery is not instant. Resolvers that already cached the old DS keep using it until its TTL expires. That TTL is set by the registry, not by you. For some TLDs it is a day. Check the TTL column in your own dig ... DS output to know how long you are waiting. A few public resolvers offer a cache flush tool for a single domain, which can speed things up for that resolver only. You could also switch the nameservers back to the old provider. That only works if the old provider is still serving the signed zone. It is also slow, because NS records at the parent are cached as well. In most cases, removing the DS is cleaner.
Once the stale DS is gone from the parent, rebuild the chain of trust in this order:
  1. Confirm the parent no longer returns a DS record. Run the +norecurse DS query against the TLD nameserver and check that the answer section is empty.
  2. Enable DNSSEC for the zone in Cloudflare. Cloudflare then shows the DS values to publish: key tag, algorithm, digest type, and digest. Some registrars ask for the DNSKEY public key instead of the DS, so check which form yours expects.
  3. Confirm that Cloudflare's nameservers now return a DNSKEY, and that +dnssec queries return RRSIG records alongside your answers.
  4. Add the new DS at the registrar and copy every field exactly. A single wrong character produces the same SERVFAIL you just fixed.
  5. After the parent publishes the new DS, query a validating resolver again. A response with NOERROR and the ad (Authenticated Data) flag in the header means the chain validates from the root to your records.
The longer-term fix is to make this order the standard procedure for any nameserver move on a signed domain. Remove the old DS first. Wait at least the DS TTL, plus some margin. Change the nameservers, and wait for the parent NS TTL. Then enable signing at the new provider and add its DS. The domain is briefly unsigned, but it never stops resolving. If an unsigned window is not acceptable, there is a multi-signer approach (RFC 8901). Both providers serve each other's keys during the transition, so the domain stays signed throughout. It only works if both the old and new providers support importing external keys, so check with both before you plan around it. Some registries and registrars also support CDS/CDNSKEY records, which let the DNS operator signal DS changes automatically. Support varies by TLD and registrar. Whenever a nameserver change is followed by SERVFAIL for some users and success for others, run the +cd comparison before anything else. If turning off validation makes the answer appear, stop looking at the zone and look at the DS record at the parent. Then add a DS check to your migration checklist, before the nameservers change rather than after.