🏛️ How to check an authoritative server
An authoritative server is the machine that actually owns a zone's records. Everything else in DNS is a copy. This page is how to go straight to the owner and confirm what it really says.
When you want this#
- Someone changed a record and you want to know whether the change is actually live, without waiting for caches
- A name resolves for some people and not others
- One of several nameservers is suspected of being out of date
- You want to rule out caching entirely
Step 1: find out who the authorities are#
Before you can ask the owner, you need to know who the owner is. NS records list the nameservers for a zone:
dig isitdns.net NS +short+short means "skip all the explanation and just print the answer values". Here is the real output:
coleman.ns.cloudflare.com.
hera.ns.cloudflare.com.Reading it: this zone has two authoritative nameservers. Either one should be able to answer any question about isitdns.net. Two or more is normal and is required practice (RFC 2182), so that one going down does not take the zone offline.
The trailing dot on each name is not a typo. It means the name is complete, ending at the root. See NS records for the full story.
Step 2: ask one of them directly#
Now ask that server yourself:
dig @coleman.ns.cloudflare.com isitdns.net SOA +norecursePiece by piece, because every part is doing a job:
@coleman.ns.cloudflare.com: send this question to this exact server. Not to your normal DNS. This server and nobody else.isitdns.net: the name being asked about.SOA: the record type. SOA is a good choice for this check because every zone has exactly one, and it carries the serial number you need in step 3. See SOA records.+norecurse: "do not do any work on my behalf." You are testing whether this server knows the answer itself. Without this flag, a server that happens to also be a resolver could go and look it up elsewhere and you would not learn anything about the server you asked.
Real output from this command:
;; flags: qr aa; QUERY: 1, ANSWER: 1, AUTHORITY: 0, ADDITIONAL: 1
isitdns.net. 1800 IN SOA coleman.ns.cloudflare.com. dns.cloudflare.com. 2410489729 10000 2400 604800 1800Step 3: read the answer#
The flags line is the important part. Ignore everything else until you have checked it.
| What you see | What it means |
|---|---|
qr | this is a response, not a question. Always present in an answer. |
aa | authoritative answer. This server owns the zone and this is its own data (RFC 1035 §4.1.1). This is the flag you came for. |
ra | recursion available. A resolver says this. An authoritative server should not. |
ad | a validating resolver checked DNSSEC. Also a resolver thing, not an authority thing. |
If aa is there, you succeeded. You reached the real owner and the data you are looking at is the source of truth. No cache is involved.
If aa is missing, one of three things happened:
- You asked a server that does not own this zone. Check the name you used in step 1.
- Your network intercepted the query and a resolver answered instead. See the interception check on the troubleshooting index. The giveaway is
rabeing set. - The server owns a different zone than the one you asked about.
Now the answer line. The SOA record's fields, in order:
coleman.ns.cloudflare.com. the primary nameserver for this zone
dns.cloudflare.com. the admin contact (an email with @ written as .)
2410489729 the SERIAL. This is the one you care about.
10000 2400 604800 1800 refresh, retry, expire, minimum TTL (seconds)The serial is a version number for the zone. Every time the zone changes, it goes up. That single number is what makes the next step work.
Step 4: check every authority agrees#
This is the check that catches the most common real-world problem: one nameserver quietly missing the latest update, so a name works for some users and not others.
Ask every authority for the serial and print them side by side:
for ns in $(dig +short NS isitdns.net); do
echo "$ns -> $(dig @"$ns" +short isitdns.net SOA | awk '{print $3}')"
doneWhat the command does: get the list of nameservers, then for each one, ask it for the SOA and pull out the third field, which is the serial.
Real output:
hera.ns.cloudflare.com. -> 2410489729
coleman.ns.cloudflare.com. -> 2410489729Reading it: both numbers are identical, so both servers hold the same version of the zone. This is what healthy looks like.
If the numbers differ, the server with the lower number has not received the latest update. Its copy is stale, and any user who happens to ask that server gets old answers. That is a zone transfer problem: see zone transfers.
What each failure answer means#
The header line of any dig output ends with status:, and that word is the diagnosis.
| Status | Means | Usual cause |
|---|---|---|
NOERROR with an answer | it worked | nothing to do |
NOERROR with ANSWER: 0 | the name exists, but not with that record type | you asked for AAAA on a name that only has A, for example |
NXDOMAIN | the name does not exist at all | typo, or the record was deleted |
REFUSED | "I am not answering that" | you asked a server about a zone it does not host |
SERVFAIL | something broke while answering | often DNSSEC validation failing, see dnssec-troubleshooting |
timed out | nothing came back | server down, firewall blocking port 53, or wrong IP |
Here is REFUSED on purpose, by asking isitdns.net's nameserver about a domain it has nothing to do with:
dig @coleman.ns.cloudflare.com google.com A +norecurse;; ->>HEADER<<- opcode: QUERY, status: REFUSED, id: 24157
;; flags: qr; QUERY: 1, ANSWER: 0, AUTHORITY: 0, ADDITIONAL: 1Reading it: REFUSED and ANSWER: 0. The server is not broken and this is not an error on your part. It is correctly saying "that is not my zone, I have nothing to tell you." Notice there is no aa, because it is not an authority for what you asked.
This is exactly the answer you get when you point a forward zone at a server that does not host the zone, which is why REFUSED is worth recognising on sight.
See also#
- Authoritative zones: what it means to own a zone
- check-a-delegation: whether the parent agrees these are the right nameservers
- check-a-forwarder: the other direction, when you are sending queries somewhere
- SOA records and NS records
- dig-flags: every
+flagexplained