Three Different Answers, Three Different Problems
When a domain won't resolve, "check DNS propagation" is the reflexive answer — and it's frequently the wrong diagnosis. DNS failures come back with specific, meaningful status codes, and each one points at a genuinely different layer of the problem. dig shows you exactly which one you're dealing with; here's what each means and how to actually fix it.
NXDOMAIN — "This Name Does Not Exist"
$ dig app.example.com
;; ->>HEADER<<- opcode: QUERY, status: NXDOMAIN, id: 41230
;; flags: qr rd ra; QUERY: 1, ANSWER: 0, AUTHORITY: 1, ADDITIONAL: 0
What it means: this is a definitive, completed answer from an authoritative source — the zone exists, but no record exists for this exact name. It is not a failure to reach a server; the server that authoritatively knows about example.com responded and confirmed app.example.com isn't in it.
The real-world causes, roughly in order of frequency:
- A typo in the record name (
aap.example.comvsapp.example.com) - The record genuinely hasn't been created yet on the authoritative nameserver
- Negative caching of an earlier NXDOMAIN — you added the record after a resolver already cached a "doesn't exist" answer for it. Per the DNS spec, negative answers get cached too, for a duration set by the zone's SOA minimum TTL — commonly a few hours, independent of the record's own TTL once it exists.
Diagnose by bypassing every cache and asking the authoritative server directly:
dig @ns1.example.com app.example.com
If that returns a real answer while your normal resolver still returns NXDOMAIN, it's cached negative data waiting to expire — not a configuration problem. If the authoritative server itself returns NXDOMAIN, the record genuinely doesn't exist there yet and needs to be added.
SERVFAIL — "Something Failed While I Was Trying to Answer"
$ dig broken.example.com
;; ->>HEADER<<- opcode: QUERY, status: SERVFAIL, id: 58821
;; flags: qr rd ra;
What it means: the name may well exist, but the resolver hit a failure trying to get a valid answer — this is fundamentally different from NXDOMAIN, which is a clean "it doesn't exist." SERVFAIL says "something broke while I was looking."
Common real causes:
- DNSSEC validation failure — an expired signature (RRSIG), a key rollover that didn't propagate correctly, or a DS record at the parent zone that no longer matches the child zone's keys
- All authoritative nameservers for the zone are unreachable or returning errors
- A malformed zone file on the authoritative server
Test the DNSSEC hypothesis directly — +cd (checking-disabled) tells the resolver to skip DNSSEC validation entirely:
dig +cd broken.example.com
If +cd returns a normal answer while a regular query returns SERVFAIL, DNSSEC validation is confirmed as the cause — check for an expired RRSIG or a DS/DNSKEY mismatch, which commonly happens after a registrar or DNS-provider migration that didn't carry over signing keys correctly.
If it still fails even with validation disabled, the authoritative servers themselves are the problem — check they're actually reachable and check the zone file for syntax errors on the primary.
REFUSED — "I Won't Answer That"
$ dig internal.corp.local @10.0.0.53
;; ->>HEADER<<- opcode: QUERY, status: REFUSED, id: 9012
What it means: unlike NXDOMAIN (name doesn't exist) or SERVFAIL (tried and failed), REFUSED is a deliberate policy decision — the server received the query and explicitly declined to process it, almost always because of access control.
Real case: querying an internal, company-only DNS server from a home network (outside the VPN) returns REFUSED — not because the record or zone is broken, but because that server is correctly configured to only answer recursive queries from its trusted internal network ranges. This is expected, correct behavior, not a bug to route around.
Other common causes:
- Querying a nameserver that's authoritative-only and doesn't perform recursion, using standard resolver-style query flags it isn't configured to accept
- An ACL or firewall rule blocking your specific source IP from that DNS server
Diagnose: if REFUSED only happens from certain networks (home, a specific office, mobile data) and not others (the corporate VPN), that confirms it's an access-control decision rather than anything wrong with the zone itself — connect through the network the server is actually meant to serve.
Quick Reference
| Status | What actually happened | Where to look |
|---|---|---|
| NXDOMAIN | Authoritative server confirmed the name doesn't exist | Typo, missing record, or negative-cache TTL not yet expired |
| SERVFAIL | A server tried to answer and failed | DNSSEC validation (dig +cd to test), or unreachable/broken authoritative servers |
| REFUSED | The server deliberately declined to answer | Access control / ACL — wrong network, not a broken zone |
| Timeout (no status) | No server responded at all | Network/firewall blocking DNS (UDP/TCP port 53), not a DNS configuration issue |
Confirming Exactly What You're Querying
A surprising number of "DNS is broken" reports turn out to be querying the wrong host entirely — a copy-pasted URL with an unexpected subdomain, a stray port, or a typo that's easy to miss by eye. ToolNinja's URL Parser → breaks a full URL down into its exact host, port, and path components, so you can confirm precisely which hostname you're actually asking DNS about before spending time debugging the wrong record.
Sources:
- The top four DNS response codes and what they mean — BlueCat Networks
- NXDOMAIN vs SERVFAIL: What Each DNS Error Means — DNSRadar
- Troubleshooting DNS Resolution Failures: Understanding and Resolving "NXDOMAIN" Errors — Broadcom Knowledge Base
- How to Troubleshoot DNS NXDOMAIN Errors — OneUptime
- Troubleshooting DNS issues with dig — Keet Malin Sugathadasa