DNS response codes (RCODE): NOERROR, NXDOMAIN, SERVFAIL, REFUSED
- tool
- DNS
- versions
- RFC 1035, RFC 6895 and the IANA DNS parameters registry
- os
- any
Every DNS response carries a response code (RCODE) in its header. NOERROR (0) means the query was answered, NXDOMAIN (3) means the name does not exist, SERVFAIL (2) means the server could not get an answer (often a DNSSEC validation failure or an unreachable authoritative server), and REFUSED (5) means the server will not answer this client. dig shows it in the header line as status: NXDOMAIN.
All registered codes
The list as implemented by dnspython, which follows the IANA registry:
uv run -q --no-project --python 3.13 --with 'dnspython==2.*' python - <<'EOF'
import dns.rcode
for code in dns.rcode.Rcode:
print(f"{int(code):>2} {code.name}")
EOFOutput
0 NOERROR 1 FORMERR 2 SERVFAIL 3 NXDOMAIN 4 NOTIMP 5 REFUSED 6 YXDOMAIN 7 YXRRSET 8 NXRRSET 9 NOTAUTH 10 NOTZONE 11 DSOTYPENI 16 BADVERS 17 BADKEY 18 BADTIME 19 BADMODE 20 BADNAME 21 BADALG 22 BADTRUNC 23 BADCOOKIE
Codes 0 to 15 fit in the 4-bit header field. Higher values (16 and up) need the EDNS(0) OPT record, which carries 8 extra bits; they are used by EDNS, TSIG and cookies.
What they mean in practice
| Code | Name | Meaning | What to check |
|---|---|---|---|
| 0 | NOERROR | Query answered | If the answer section is empty, this is NODATA: the name exists but has no record of that type |
| 1 | FORMERR | The server could not parse the query | Old servers or middleboxes that reject EDNS; try dig +noedns |
| 2 | SERVFAIL | The server failed to produce an answer | DNSSEC validation (dig +cd succeeds?), authoritative servers unreachable, broken delegation |
| 3 | NXDOMAIN | The name does not exist | Typos, missing record, wrong zone, search domain appended |
| 4 | NOTIMP | Query type or opcode not implemented | Unusual opcodes or types |
| 5 | REFUSED | The server refuses to answer | Querying an authoritative-only server for another zone, or a resolver that only serves its own network |
| 6 | YXDOMAIN | Name exists when it should not | Dynamic updates (RFC 2136) with prerequisites |
| 7 | YXRRSET | RRset exists when it should not | Dynamic updates |
| 8 | NXRRSET | RRset that should exist does not | Dynamic updates |
| 9 | NOTAUTH | Server not authoritative for the zone, or TSIG not authorised | Dynamic updates, zone transfers |
| 10 | NOTZONE | Name not in the zone | Dynamic updates |
| 16 | BADVERS / BADSIG | Unsupported EDNS version / bad TSIG signature | EDNS version, TSIG key |
| 17-22 | BADKEY, BADTIME, BADMODE, BADNAME, BADALG, BADTRUNC | TSIG and TKEY errors | Shared key, clock skew between servers |
| 23 | BADCOOKIE | Bad or missing server cookie | DNS cookies (RFC 7873); clients retry with the new cookie |
NXDOMAIN vs NODATA
Both mean "no record", but they are different answers. NXDOMAIN says the name has no records of any type. NODATA is NOERROR with an empty answer: the name exists, but not with the requested type (for example an AAAA query for a host that has only an A record). Resolvers cache both negative answers for the time given by the zone's SOA record (RFC 2308).