Every DNS response carries a four-bit response code — the rcode — in its header. It is the first thing to read when a lookup goes wrong, because it tells you whose problem this is. NXDOMAIN points at the query. SERVFAIL points at the zone or the path to it. REFUSED points at policy. NOERROR with an empty answer section points at the record type you asked for. Get the rcode first and you skip most of the guesswork.
# The rcode is on the HEADER line
dig example.com A | grep 'HEADER'
# ;; ->>HEADER<<- opcode: QUERY, status: NOERROR, id: 12294
# Just the status, for scripting
dig +noall +comments example.com A | grep -o 'status: [A-Z]*'What does each response code mean?
| Rcode | Name | Means | Whose problem |
|---|---|---|---|
| 0 | NOERROR | The query succeeded. May still have an empty answer section. | Nobody — or the record type you asked for does not exist. |
| 1 | FORMERR | The server could not interpret the query. | The client, or a middlebox mangling packets. |
| 2 | SERVFAIL | The server could not produce a valid answer. | The zone, its nameservers, or DNSSEC validation. |
| 3 | NXDOMAIN | The name authoritatively does not exist. | Whoever typed or generated the name — or a missing record. |
| 4 | NOTIMP | The server does not support the requested opcode. | Rare; the server. |
| 5 | REFUSED | The server can answer but chooses not to. | Policy — you queried a server that will not serve you. |
| 9 | NOTAUTH | The server is not authoritative for the zone. | Configuration; usually a stale or wrong delegation. |
What NXDOMAIN really tells you
NXDOMAIN is a *successful* lookup with a negative result. Some authoritative server for the zone was reached, understood the question, and stated that the name does not exist. That is a reliable, trustworthy answer — which is precisely why it is cacheable. The response includes the zone's SOA record in the authority section, and the SOA's minimum field caps how long resolvers may remember the non-existence.
dig this-name-does-not-exist-9182734.com A
# ;; ->>HEADER<<- opcode: QUERY, status: NXDOMAIN, id: 59818
# ;; flags: qr rd ra; QUERY: 1, ANSWER: 0, AUTHORITY: 1, ADDITIONAL: 1
#
# ;; AUTHORITY SECTION:
# com. 900 IN SOA a.gtld-servers.net. nstld.verisign-grs.com. 1788212390 1800 900 604800 900- The name is genuinely missing. A typo, an expired domain, or a record nobody ever created. Check the domain itself with the WHOIS Lookup.
- You created the record but the SOA in the response is your own zone. That means your nameservers are answering and saying "no such name" — the record is not where you think it is, or the host field was entered wrong.
- The SOA belongs to the TLD, not your zone. The delegation itself is missing: the domain is not registered, has expired, or the registry is not publishing NS records for it. Confirm with the NS Record Lookup.
- Negative caching is holding an old answer. If the record was created recently, resolvers that asked earlier will keep returning NXDOMAIN until the SOA minimum expires. Read the value with the SOA Record Lookup.
What SERVFAIL really tells you
SERVFAIL is the resolver saying "I tried and I have nothing valid for you." It is not a statement about the name, and it is not cacheable as a fact — resolvers cache the failure only briefly to avoid hammering a broken zone. Because it is a catch-all, the same rcode covers several very different faults.
- DNSSEC validation failure. This is the most common cause on a healthy-looking domain, and the most confusing, because unvalidating resolvers return the record happily while validating ones refuse. Typically the DS record at the registry no longer matches the DNSKEY in the zone — the classic aftermath of a nameserver migration with DNSSEC left enabled.
- All authoritative nameservers unreachable. Firewalled, down, or delegated to hostnames that themselves do not resolve. A "lame delegation" — NS records pointing at servers that are not configured for the zone — produces the same symptom.
- The zone failed to load on the authoritative server. A syntax error or failed transfer means the server has no data and cannot answer for a zone it is supposed to own.
- Response size or transport problems. Large signed responses that cannot fall back to TCP, or a middlebox dropping EDNS, can surface as intermittent SERVFAIL for some queries and not others.
- Resolver-side limits. Extremely long CNAME chains or delegation loops cause the resolver to give up.
How do you prove SERVFAIL is a DNSSEC problem?
Ask the same resolver to skip validation. The +cd flag sets the Checking Disabled bit, which tells a validating resolver to return the data without verifying signatures. If the query fails normally but succeeds with +cd, the data exists and validation is what is rejecting it.
# Fails: the resolver validates and the chain is broken
dig @8.8.8.8 dnssec-failed.org A | grep 'status:'
# ;; ->>HEADER<<- opcode: QUERY, status: SERVFAIL, id: 45093
# Succeeds: same resolver, validation disabled
dig +cd @8.8.8.8 dnssec-failed.org A | grep 'status:'
# ;; ->>HEADER<<- opcode: QUERY, status: NOERROR, id: 53287Google Public DNS and Cloudflare both return an Extended DNS Error (RFC 8914) explaining the failure. Recent versions of dig print it as a line like ; EDE: 6 (DNSSEC Bogus); older versions show the raw OPT=15 option, whose decoded text is still readable — for dnssec-failed.org it reads "No DNSKEY matches DS RRs of dnssec-failed.org", which names the fault exactly. Confirm the chain with the DNSSEC Checker.
REFUSED and NOERROR-with-no-answer
REFUSED means the server understood you and declined. Almost always you asked the wrong server: an authoritative nameserver will refuse recursive queries for zones it does not host, and a resolver will refuse clients outside its access list. It is a policy answer, not a fault in the zone.
# Asking a nameserver about a zone it does not serve
dig @a.iana-servers.net google.com A | grep 'status:'
# ;; ->>HEADER<<- opcode: QUERY, status: REFUSED, id: 60705NOERROR with `ANSWER: 0` — often called NODATA — is the subtlest of the four. The name exists, but not with the record type you asked for. Querying AAAA on an IPv4-only host, MX on a domain that does not receive mail, or TXT on a host with none all produce this. The answer section is empty and the authority section carries the SOA. This is a completely normal response and not an error; if your tooling reports it as a failure, the tooling is wrong.
To see the whole picture at once — which types exist, which do not, and what the authoritative servers say — run the DNS Lookup. For type-specific checks use the A Record Lookup, CNAME Lookup, or MX Lookup. If a browser is showing the error rather than a command line, Fix DNS_PROBE_FINISHED_NXDOMAIN covers the client-side half.