Quick Summary
To query an authoritative DNS server, put @ before the nameserver hostname or IP and add +norecurse: dig @ns1.example.net example.com A +norecurse. If the flags line comes back with aa, that server owns the zone and you are reading the real thing.
- Get the nameserver list first with dig NS example.com +short, then go at each one directly.
- No aa flag means a cached copy.
- Compare the SOA serial across every nameserver in the list. They should all match, and when they don't, you have found your bug.
- A SERVFAIL from a resolver usually means it could not reach the authoritative servers, though DNSSEC is the other common cause.
- Glue records show up in the additional section of the parent zone's answer, and only when the nameserver sits inside its own zone.
What an Authoritative DNS Server Actually Answers
An authoritative nameserver holds the zone file for a domain and answers from it. A recursive resolver, the kind your laptop or office network uses, holds no zone at all: it asks the authoritative servers on your behalf and caches what they say for as long as each record's TTL allows.
That cache is why the two can disagree. Right after a record change, the authoritative server already has the new value while a resolver can keep handing out the old one until its cached copy expires. Querying the authoritative server directly takes the cache out of the picture and tells you what the zone says right now.
Find Authoritative Nameservers for a Domain
Every direct query in this guide needs a nameserver to send it to, so start by asking for the domain's NS records. Put your own domain in place of example.com:
dig NS example.com +short
On Windows, nslookup -type=NS example.com returns the same list.
The output is a list of hostnames. Those are the authoritative DNS nameservers for the domain, and each one is a target you can query directly. Their names depend on who hosts your DNS:
| DNS host | What the NS records look like |
|---|---|
| Amazon Route 53 | ns-718.awsdns-25.net, ns-1079.awsdns-06.org |
| Cloudflare | elliott.ns.cloudflare.com, hera.ns.cloudflare.com |
| A registrar's own DNS | Usually the registrar's name, such as ns1.<registrar>.com |
The rest of this guide writes ns1.example.net as a stand-in. It is a placeholder, not a server you can query: use one of the hostnames your own NS lookup returned in its place. Guessing ns1.yourdomain.com usually fails with couldn't get address for 'ns1.yourdomain.com': not found, because most domains have no nameserver by that name.
The parent zone is worth asking too. A query to a TLD server returns the delegation, which carries the NS records the registrar published:
dig NS +short com
dig @a.gtld-servers.net example.com NS +norecurse
The first line lists the servers for .com, and the second asks one of them for the delegation. If its NS list and the zone's own list disagree, you have found something worth looking at before you go any further.
Reading NS Records and Glue Records
Glue records are A and AAAA records published in the parent zone, and they exist to break a circular dependency.
The dependency works like this. To reach ns1.example.com, a resolver needs the IP address of ns1.example.com. To get that address, it needs to reach ns1.example.com. Glue breaks the loop by having the parent hand out the address along with the referral.
To spot glue, look at the ADDITIONAL SECTION of the parent's answer, from the dig @a.gtld-servers.net query above. A or AAAA records there for the nameservers mean the parent zone is carrying glue.
Glue only turns up when the nameserver hostname lives inside the zone it serves. Put your nameservers on a separate domain and there is nothing to glue, so nothing appears, which trips people up when they go looking for records that were never supposed to be there.
Run a dig Query Against an Authoritative Nameserver
This is the core command. Put @ in front of a nameserver hostname or IP and dig sends the query straight there, skipping your resolver entirely. Swap ns1.example.net for a nameserver from your dig NS output and example.com for your domain.
dig @ns1.example.net example.com A +norecurse
The +norecurse flag tells the server not to go chasing the answer elsewhere. An authoritative server would not recurse anyway, so strictly speaking you can leave it off, but it makes the intent obvious to whoever reads the command later.
Read the output top down. The status line tells you whether the name exists: NOERROR yes, NXDOMAIN no. Next is the flags line, where you want to see aa. Then the ANSWER SECTION with the record data itself. Query type SOA and the serial is in there as well.
Change the type argument for other record types:
dig @ns1.example.net example.com MX +norecurse
dig @ns1.example.net example.com TXT +norecurse
dig @ns1.example.net example.com SOA +norecurse
Once you have a known-good answer from the source, you can compare what different resolvers return and see who is still behind.
The Same Query in nslookup and host
Not every machine has dig on it. Windows ships nslookup, and macOS and most Linux distributions carry host.
nslookup sends the query to whatever server you name after the command, then prints the answer block:
nslookup -type=A example.com ns1.example.net
The syntax is the same on Windows. The output names the responding server and tags the answer "Non-authoritative", or drops that tag when the reply carries the aa flag, which is a slightly backwards way of telling you what dig says outright.
host is terser and much easier to script around:
host -t A example.com ns1.example.net
host -t MX example.com ns1.example.net
host -t SOA example.com ns1.example.net
host only prints the aa status if you ask for verbose output (host -v), so for a quick authoritative check dig still wins. host is the right tool when you want one line per record and none of the header noise.
| Tool | Direct-query syntax | Shows aa flag by default | Ships with |
|---|---|---|---|
| dig | dig @server name type +norecurse | Yes | macOS; Linux in the dnsutils or bind-utils package; BIND tools on Windows |
| nslookup | nslookup -type=type name server | No, prints "Non-authoritative" label instead | Windows, macOS, most Linux |
| host | host -t type name server | Only with -v | macOS, most Linux |
Turn Off Recursion Explicitly
A resolver will cheerfully answer from cache and label the reply non-authoritative, which is honest of it but not what you are after. Combine @server with +norecurse in dig to get a clean answer from the source. nslookup needs the recursion flag turned off before you query:
nslookup
> set norecurse
> server ns1.example.net
> example.com
host turns recursion off with -r, as in host -r -t A example.com ns1.example.net. It still only shows the aa flag with -v, which is one more reason dig ends up being the default for this kind of check.
A direct query with recursion disabled gives you either the record with aa set or an error. Nothing cached sneaks through. That is the whole value of it when you are trying to work out whether a change actually landed at the source.
Trace the Delegation from Root to Child Zone
+trace walks the hierarchy for you: root servers, then TLD servers, then the authoritative servers, printing each hop.
dig example.com +trace
The last block is the answer from the authoritative server, and everything above it is the delegation chain. When something is broken partway down, this is usually where it shows itself.
Treat +trace with some care, though. It does its own recursion, which makes it a diagnostic rather than a direct query, and people sometimes treat its output as proof of what a given server returned. Use it to find the servers. Then query them with @.
DNS SOA Record Lookup: The Serial and Refresh Fields
The SOA record is the zone's control record, holding the serial, the primary nameserver, and the timing values that secondaries use to stay in sync.
dig @ns1.example.net example.com SOA +norecurse
Seven fields come back. Two of them matter for most day-to-day work: the serial, which has to go up every time the zone changes, and the refresh value, which sets how often a secondary checks the primary. Two nameservers reporting different serials means one of them is stale.
The rest are retry, expire, minimum TTL, and the responsible mailbox, and you can mostly ignore them until you are tuning replication. The classic mistake here is editing records on one nameserver and forgetting the other, and a serial comparison will surface that faster than reading the records by eye.
So run the SOA query against every nameserver in the NS list, not just the first one. The serials should all match.
Read the DNS Response Authoritative Flag
The aa flag in the response header is your proof that you asked the right server. Present means the server owns the zone and the answer is authoritative.
Missing aa narrows it down to two possibilities. Either you queried a recursive resolver by mistake, or you queried a server that is not authoritative for that zone at all.
You need full dig output to see it, so skip +short here. The flags line sits near the top:
;; flags: qr aa rd; QUERY: 1, ANSWER: 1, AUTHORITY: 1, ADDITIONAL: 0
A response without aa gets labeled non-authoritative, and you should treat it as a cached copy. It may well be correct. It just did not come from the source, so it cannot settle an argument about what the zone currently says.
When a record change looks like it has not taken effect, start with this check. If the authoritative server hands back the new value with aa set, the zone is fine and whatever is going wrong is happening downstream in somebody's cache.
Troubleshooting SERVFAIL, NXDOMAIN, and Timeouts
Most DNS problems land in one of three failure states, each pointing somewhere different. The order you check them in matters as much as knowing what they mean.
| Response | What it means | First check |
|---|---|---|
| SERVFAIL | Server could not complete the lookup | Query the authoritative server directly |
| NXDOMAIN | The name does not exist in the zone | Confirm the exact hostname and zone |
| Timeout | No response within the wait window | Check the nameserver IP and port 53 |
No aa flag | Answer came from cache, not the source | Re-query with @nameserver |
| Serial mismatch | One nameserver is behind | Compare SOA serials across all NS |
Work the Sequence in This Order
Start with a direct query to each authoritative nameserver:
dig @ns1.example.net example.com A +norecurse
dig @ns2.example.net example.com A +norecurse
If neither one answers, stop looking at resolvers. The zone is the problem.
SERVFAIL from a resolver usually means the resolver could not reach the authoritative servers, so query them yourself. A successful direct query points at the resolver or the delegation rather than the zone. The other common cause is DNSSEC, where a validating resolver returns SERVFAIL on a failed signature while the authoritative server answers perfectly well. To check, query with +cd (checking disabled) and see whether the data comes back once validation is out of the way:
dig +cd example.com A
An answer with +cd and a SERVFAIL without it means the delegation is signed but the chain is not validating.
NXDOMAIN is definitive when it comes from an authoritative server. The name does not exist, and no amount of retrying will change that.
Timeouts tend to be a firewall blocking port 53 or a nameserver that is simply down. If one server times out and another answers, you have narrowed it to that one host.
When the Answer Is Right but Resolvers Disagree
A direct query returning the correct value while resolvers serve something else is not a zone problem, it is caching playing out in public. The TTL on the old record decides how long the stale answer sticks around, which is why lowering the TTL ahead of a planned change is standard practice.
Check whether the answer is still propagating across resolvers before you touch anything else. Editing a record that is already correct at the source just gives resolvers a second change to catch up with, and now you are waiting on two TTLs instead of one.
Check DNSSEC Delegation Before You Trust the Answer
DNSSEC puts a cryptographic signature on DNS answers. Before you lean on an answer, it is worth confirming that the delegation is signed and that the chain actually validates.
Start at the parent with the DS record:
dig DS example.com +short
A DS record means the parent vouches for the child's signing key. No DS record means resolvers treat the zone as unsigned, even if it carries signatures, and validation stops right there. Many DNS hosts now publish the DS for you, following the practices in RFC 10026 on DNSSEC delegation signer automation.
Then ask the child zone for its DNSKEY:
dig @ns1.example.net example.com DNSKEY +dnssec +norecurse
An RRSIG record alongside the DNSKEY means the zone is signed. With a matching DS record at the parent, the chain is intact.
A validation failure comes back as SERVFAIL from a validating resolver even though the authoritative server answers fine, and that split confuses almost everyone the first time they hit it. The direct query proves the data is there. The resolver's SERVFAIL proves the signature does not check out. Both are true at once.
For the wider picture of which records decide whether mail from a domain gets trusted, have a look at the DNS records that email authentication depends on.
Verify Your Sending Domain Records in SEMAOS
These same commands work for checking a sending domain. Add a custom sending domain in SEMAOS, on a paid plan, and the setup screen lists what you need at your DNS host: an ownership TXT record, three DKIM CNAMEs, and MX and SPF records on the mail subdomain. The usual snag is a DNS host that quietly appends the zone name to records you enter, so verify with a direct query rather than trusting the control panel's display. Set up your sending domain and add the records SEMAOS shows you.
Query each record type against the authoritative nameserver rather than a resolver. Replace ns1.yourhost.com with a nameserver from dig NS example.com +short and example.com with your sending domain:
dig @ns1.yourhost.com example.com TXT +norecurse
dig @ns1.yourhost.com mail.example.com MX +norecurse
Each answer should come back with aa set and the exact value SEMAOS showed you. When all of them do, the records are right at the source, and any resolver still showing something else is serving a cached copy.
FAQ
How do I query an authoritative DNS server with dig?
Put @ before the nameserver hostname or IP and add +norecurse, for example: dig @ns1.example.net example.com A +norecurse. Get the nameserver list first with dig NS example.com +short.
What does the aa flag mean in a dig response?
The aa flag in the flags line means the answering server is authoritative for the zone. Missing aa means either you queried a recursive resolver by mistake or the server is not authoritative for that zone, so treat the answer as a cached copy.
Why do two nameservers return different SOA serials?
The serial has to increase every time the zone changes, so differing serials mean one nameserver is stale. The usual cause is editing records on one nameserver and forgetting the other. Run the SOA query against every nameserver in the NS list, not just the first.
What causes a SERVFAIL when the authoritative server answers fine?
Usually DNSSEC. A validating resolver returns SERVFAIL when a signature fails to check out, even though the authoritative server answers normally. Query with dig +cd to disable checking. If the data comes back, the delegation is signed but the chain is not validating.