When a domain resolves to the wrong place, stops resolving, or resolves differently for different people, the fastest way to find out why is to ask DNS servers directly and read their answers line by line. dig, nslookup and PowerShell's Resolve-DnsName are on almost every administrator's machine, yet their output is often skimmed for one IP address while the flags, status codes, TTLs and authority data that explain the problem are ignored. This guide shows how to read a DNS answer, how to trace a delegation from the root to the authoritative servers, how to compare resolvers, and how to recognise signs of hijacking, filtering or DNSSEC failure. It is for network engineers, SOC analysts and incident responders working on systems and domains they are authorised to investigate.
Key takeaways
- Read the header, not just the answer. The status (NOERROR, NXDOMAIN, SERVFAIL, REFUSED) and the flags (aa, rd, ra, ad, tc) tell you who answered and how far to trust it.
- Ask the authoritative servers directly. A recursive resolver shows you what is cached; the authoritative servers show you what the zone owner published.
- Trace the delegation.
dig +tracefollows referrals from the root, which exposes wrong NS records at the registry or parent zone, the usual mark of a registrar-level hijack. - Compare views. The same query sent to the internal resolver, a public resolver and the authoritative server separates local filtering or split-horizon from a change to the zone itself.
- Use DNSSEC and Extended DNS Errors as evidence. The ad flag, a SERVFAIL that disappears with
+cd, and EDE codes such as "DNSSEC Bogus", "Blocked" or "Forged Answer" explain failures that a bare IP address cannot.
Choosing the tool
| Task | dig (BIND) | nslookup (Windows) | Resolve-DnsName (PowerShell) |
|---|---|---|---|
| Query a specific server | dig @192.0.2.53 example.com | nslookup example.com 192.0.2.53 | Resolve-DnsName example.com -Server 192.0.2.53 |
| Choose record type | -t MX or example.com MX | -type=MX or set type=MX | -Type MX |
| Reverse lookup | -x 192.0.2.10 | nslookup 192.0.2.10 | -Type PTR |
| No recursion | +norecurse | set norecurse | -NoRecursion |
| Force TCP | +tcp | set vc | -TcpOnly |
| DNSSEC data | +dnssec (sets the DO bit) | Limited | -DnssecOk |
| Checking disabled | +cd | Not available | -DnssecCd |
| Trace from the root | +trace | Not available | Not available |
| Full packet detail | Default output | -debug or set d2 | Object properties |
| Bypass hosts file and cache | dig never uses the hosts file | Queries DNS directly | -DnsOnly, -NoHostsFile |
Two behaviours cause frequent confusion. dig sends queries to the servers in /etc/resolv.conf unless told otherwise, and reads per-user defaults from ~/.digrc (the -r option skips it for predictable scripts). nslookup and dig both bypass the operating system's resolver logic, so a browser that uses the hosts file, a local cache or encrypted DNS can see a different answer from either tool. When the user's experience and dig disagree, test with Resolve-DnsName or the OS resolver as well.
Reading a dig answer
A default dig answer has a header, then the question, answer, authority and additional sections, then statistics. The parts that matter for investigation:
| Field | Meaning | What to look for |
|---|---|---|
status: NOERROR | RCODE 0, no error | With an empty answer section this is NODATA: the name exists but has no record of that type |
status: NXDOMAIN | RCODE 3, name error: the name does not exist | Authority section should carry the zone's SOA; a resolver returning an IP for a name that should be NXDOMAIN suggests rewriting |
status: SERVFAIL | RCODE 2, server failure | Often DNSSEC validation failure or unreachable authoritative servers; retry with +cd |
status: REFUSED | RCODE 5, refused for policy reasons | Querying a server that does not serve you (an authoritative server asked for recursion, or an ACL) |
aa flag | Authoritative answer | Present only when the responding server is authoritative for the name |
rd / ra | Recursion desired / available | ra on an internet-facing authoritative server can indicate an open resolver |
ad flag | Authenticated data | Set by a validating resolver when the answer passed DNSSEC validation |
tc flag | Truncated | The answer did not fit; dig retries over TCP. Blocked TCP 53 breaks large answers |
| TTL column | Seconds the record may be cached | A TTL counting down shows a cached answer; a full TTL comes from the authoritative server or a fresh fetch |
OPT PSEUDOSECTION | EDNS data | Advertised UDP buffer size, NSID and Extended DNS Error (EDE) codes appear here |
SERVER: line | Who actually answered | Confirm it is the server you meant to query |
The RCODE meanings come from RFC 1035, which also defines the aa, tc, rd and ra flags and the original 512-byte limit for DNS over UDP. RFC 2308 defines negative caching: NXDOMAIN and NODATA answers include the zone's SOA record, and the negative TTL is the lower of the SOA's MINIMUM field and the SOA record's own TTL. That explains why a record you have just created can stay "missing" for a while: the earlier negative answer is still cached.
Useful output options: +short for terse answers in scripts, +noall +answer to show only the answer section, +multiline for readable SOA and DNSKEY records, and +ttlunits for human-readable TTLs.
nslookup output and messages
nslookup prints the server it used, then the answer. "Non-authoritative answer" means the data came from a resolver rather than from a server authoritative for the zone; it is normal for recursive lookups and is not a warning. Microsoft documents the error messages as follows:
- Nonexistent domain: the name does not exist (NXDOMAIN).
- No records: the name exists but has no records of the requested type (NODATA).
- Server failure: the server could not return a valid answer.
- Refused: the server refused to service the request.
- Timed out / No response from server: no reply within the timeout and retries, or no DNS service on that address. Adjust with
set timeoutandset retry.
For investigation, nslookup -debug or interactive set d2 prints every field of the packets, including TTLs and the authority section, which the default output hides.
Tracing delegation from the root
dig +trace example.com makes iterative queries starting at the root servers and shows each referral: root to the top-level domain servers, TLD servers to the domain's name servers, then the final answer. Each step should be checked against what you expect.
- TLD referral: the NS records returned by the TLD servers come from the registry, which takes them from the registrar. If these differ from the name servers you operate, the change was made at the registrar or registry, not in your zone.
- DS records: for a signed zone, the parent returns DS records. A DS that does not match your DNSKEY makes the whole zone fail validation (SERVFAIL on validating resolvers).
- Final answer: confirm the last hop came from one of your authoritative servers and that the aa flag is set.
Alternatives when +trace is blocked by a firewall that only allows the internal resolver: query each authoritative server directly with dig @ns1.example.net example.com SOA +norecurse and compare serial numbers. Different SOA serials between authoritative servers mean a secondary has not transferred the latest zone. +nssearch queries each authoritative server for the SOA in one command.
See the DNS Protocol Fundamentals for Defenders Guide for how referrals and glue records work.
Comparing answers across resolvers
Most DNS investigations come down to one question: who sees what? Send the same query to four places and compare.
| Answer pattern | Likely explanation | Next check |
|---|---|---|
| Authoritative correct, internal resolver wrong | Stale cache, split-horizon view, internal override zone or filtering policy | TTL on the internal answer; resolver's RPZ or policy logs; EDE codes |
| Authoritative wrong, all resolvers wrong | Zone changed: authorised change, mistake, or compromised DNS provider account | Zone change history and DNS provider audit logs |
| TLD referral points to unknown name servers | Registrar or registry change | Registrar account audit log, registry lock status, WHOIS/RDAP update date |
| Public resolver wrong, others correct | Poisoned or stale cache at that resolver, or geolocated answers | Query again after TTL expiry; check whether the zone uses location-based answers |
| One user's machine wrong | Hosts file, local malware, rogue DHCP-supplied resolver, VPN or encrypted DNS setting | Resolve-DnsName with and without -DnsOnly; configured resolvers on the interface |
| NXDOMAIN at authoritative, IP address from resolver | NXDOMAIN rewriting by an ISP, a filter or malware | EDE codes; query over a different network |
Location-based and load-balanced zones return different answers by design. Know which of your zones do this before treating a difference as tampering. See the Split-Horizon DNS Guide.
Spotting tampering and hijacking
CISA's Emergency Directive 19-01 (January 2019) described a campaign in which attackers obtained credentials for accounts that could change DNS records, altered A, MX and NS records to point to their infrastructure, and obtained valid certificates for the hijacked domains so intercepted traffic raised no browser warnings. The directive required agencies to audit public DNS records on authoritative and secondary servers, change passwords and enable MFA on accounts that can change DNS records, and monitor Certificate Transparency logs. The checks below put that into practice with the tools in this guide.
- Baseline and diff: keep a record of expected NS, A, AAAA, MX, TXT (SPF, DMARC, verification tokens), CAA and DS records for important domains, query the authoritative servers on a schedule, and alert on any difference.
- Delegation check: compare NS records at the TLD (from
+trace) against your intended name servers. A delegation change is high impact and should be rare. - Mail records: an MX change is a classic interception route; check MX alongside A records.
- Unusual TTLs: a sudden drop to very short TTLs ahead of a change, or records with TTLs that do not match your zone's standards, are worth investigating.
- Certificates: pair DNS checks with Certificate Transparency monitoring for certificates you did not request. See the Certificate Transparency Monitoring Guide.
- Server identity:
+nsidasks the server to identify the instance that answered, which helps when an anycast address returns inconsistent results.
Relevant ATT&CK techniques for this work include T1584.002 Compromise Infrastructure: DNS Server, T1071.004 Application Layer Protocol: DNS and T1568 Dynamic Resolution. For response steps, use the DNS Hijack Playbook.
DNSSEC and Extended DNS Errors
- Validation status: query a validating resolver with
+dnssec. The ad flag shows the answer validated. RRSIG records appear alongside signed data. - SERVFAIL that clears with +cd: if
dig example.comreturns SERVFAIL butdig +cd example.comreturns data, validation is failing. Common causes are expired signatures, a DS record at the parent that no longer matches the zone's keys, or a broken key rollover. It can also mean the data was forged, so do not simply disable validation. - Extended DNS Errors (RFC 8914): resolvers that support EDE add an INFO-CODE in the OPT pseudosection, using EDNS option code 15. Useful codes include 3 Stale Answer, 4 Forged Answer, 6 DNSSEC Bogus, 7 Signature Expired, 9 DNSKEY Missing, 15 Blocked, 16 Censored, 17 Filtered, 18 Prohibited and 22 No Reachable Authority.
- Protective DNS: a "Blocked" or "Filtered" EDE, or a known sinkhole address, usually means your own protective DNS policy acted. Check the policy before treating it as an attack. See the Protective DNS Guide.
See the DNSSEC Deployment Guide for signing and key rollover.
Transport and size problems
- Truncation: if dig shows
tcor "Truncated, retrying in TCP mode" and then times out, TCP port 53 is blocked between you and the server. Large DNSSEC, TXT and ANY responses need TCP. - EDNS buffer size:
+bufsizesets the UDP size advertised with EDNS0. Testing with a smaller value helps diagnose middleboxes that drop fragmented UDP. - Timeouts: dig retries UDP and TCP queries three times by default (
+tries) and+timeoutsets the wait per try. Raise both when testing slow links rather than concluding a server is down. - Client subnet:
+subnetsends an EDNS Client Subnet option, which lets you see what a location-aware zone returns for a given network. - Encrypted DNS: recent dig builds support DNS over TLS and HTTPS options. Clients using encrypted DNS bypass the internal resolver, which matters when internal and external answers differ. See the Encrypted DNS Enterprise Guide.
Where identity fits
Most DNS hijacks are identity incidents first. The records change because someone signed in to a registrar, DNS hosting account or DDI platform with valid credentials, or used an API token with zone-write rights. When dig shows an unexpected change at the authoritative servers or the TLD, the next step is the audit log of the account that can make that change: who signed in, from where, and whether MFA was used. API tokens used by automation to update DNS (certificate issuance, infrastructure as code) are non-human identities with the same power and should be scoped to specific zones, stored in a secrets manager and rotated. See the Authoritative DNS and Registrar Account Security Guide.
A repeatable investigation workflow
- Record the symptom: exact name, record type, time, affected users and networks.
- Query the local view: Resolve-DnsName (or the OS resolver) and the configured internal resolver; note status, TTL and any EDE.
- Query authoritatively: each authoritative server with
+norecurse; confirm aa and compare SOA serials. - Trace delegation:
+traceand compare NS and DS at the parent with your intended values. - Compare public resolvers: at least two independent ones, to separate local issues from global ones.
- Check DNSSEC:
+dnssec, then+cdif there is a SERVFAIL. - Correlate: zone change history, DNS provider and registrar audit logs, resolver logs and Certificate Transparency.
- Preserve evidence: save full dig output with timestamps (not
+short) before caches expire, because answers change as TTLs run down.
Run active queries only against resolvers and zones you are authorised to test, and avoid high-rate scripted queries against third-party servers.
Detection and measurement
One-off dig commands find problems; scheduled checks prevent surprises. Build a small job that queries the authoritative servers and the TLD for each important domain and compares the results with a baseline. Feed resolver logs into the SIEM as described in the DNS Logging and Detection Guide.
- Number of important domains with automated authoritative and delegation checks (target: all).
- Time from an unauthorised record or delegation change to alert.
- Count of SERVFAIL responses caused by DNSSEC validation failures for your own zones.
- SOA serial mismatches between authoritative servers lasting longer than the refresh interval.
- Percentage of DNS provider and registrar accounts with MFA and registry lock enabled where offered.
Framework mapping
| Framework | Reference | Relevance |
|---|---|---|
| NIST SP 800-53 Rev. 5 | SC-20, SC-21, SC-22, SI-4 | Secure authoritative and recursive resolution, resolution architecture, system monitoring |
| NIST CSF 2.0 | DE.CM-01, DE.AE-02 | Monitoring networks and network services, analysing adverse events |
| CIS Controls v8.1 | Control 9 (Email and Web Browser Protections), Control 13 (Network Monitoring and Defense) | DNS filtering and network monitoring |
| ISO/IEC 27001:2022 Annex A | A.8.16 Monitoring activities, A.8.20 Networks security | Monitoring and network service security |
| MITRE ATT&CK | T1584.002, T1071.004, T1568 | DNS server compromise, DNS as a command channel, dynamic resolution |
Common failure patterns
- Testing only the internal resolver: a cached or filtered answer is taken as the truth about the zone.
- Using +short during an incident: the status, flags, TTLs and EDE codes that would explain the problem are thrown away.
- Disabling DNSSEC validation to "fix" SERVFAIL: this hides expired signatures and can also hide forged answers.
- Ignoring the parent zone: checking records in your own zone while the TLD delegation points somewhere else.
- Forgetting negative caching: declaring a new record broken when an earlier NXDOMAIN is still cached for the SOA negative TTL.
- Not saving evidence: answers are lost once TTLs expire and records are corrected.
Practitioner checklist
- Keep dig (or Resolve-DnsName on Windows) available on admin and SOC workstations.
- Record expected NS, MX, A, TXT, CAA and DS values for every important domain.
- Query authoritative servers with
+norecurseand confirm the aa flag before concluding anything. - Use
+traceto confirm the TLD delegation matches your name servers. - Compare internal, public and authoritative answers for every reported resolution problem.
- Diagnose SERVFAIL with
+dnssecand+cdand read any EDE codes. - Schedule automated authoritative and delegation checks with alerting on change.
- Save full dig output with timestamps as evidence during incidents.
- Check registrar and DNS provider audit logs whenever authoritative data changes unexpectedly.
Standards and references
- IETF: RFC 1035 Domain Names, Implementation and Specification
- IETF: RFC 2308 Negative Caching of DNS Queries
- IETF: RFC 8914 Extended DNS Errors
- ISC: BIND 9 manual pages, dig
- Microsoft: nslookup command reference
- Microsoft: Resolve-DnsName
- CISA: Emergency Directive 19-01, Mitigate DNS Infrastructure Tampering
- NIST: SP 800-53 Rev. 5
Related NHI Mgmt Group resources: DNS Protocol Fundamentals for Defenders Guide · DNS Hijack Playbook · DNS Logging and Detection Guide · Authoritative DNS and Registrar Account Security Guide · Passive DNS and DNS History Guide