🔎 How to check a resolver
Your resolver is the server your machine asks when it needs to turn a name into an address. It is the first thing in the path and the most common place for the path to go wrong.
Step 1: which resolver are you even using?#
Most people are wrong about this. The setting you configured is not always the one in use.
On Linux:
resolvectl status | grep -A2 "Current DNS"On older Linux systems, or inside a container:
cat /etc/resolv.confLook for the nameserver lines. That is who your machine asks.
On macOS:
scutil --dns | grep nameserver | head -5On Windows, in PowerShell:
Get-DnsClientServerAddress -AddressFamily IPv4A common surprise: on modern Linux you will often see 127.0.0.53. That is not a real remote server, it is a local stub on your own machine that forwards to the real one. resolvectl status shows you what sits behind it.
Another surprise: your browser may not use this at all. Firefox and Chrome can be configured with their own encrypted DNS, which in both cases means DoH (RFC 8484) and not DoT, and it bypasses your system setting entirely. If a name works in the terminal but not the browser, or the other way around, that difference is the first thing to check. See dot-doh.
Step 2: does it answer?#
Ask it something simple:
dig @1.1.1.1 isitdns.net A +shortSwap 1.1.1.1 for your own resolver's IP. Real output:
104.21.56.211
172.67.155.242Reading it: two IPv4 addresses, so the name resolves. Two is normal; many services publish several addresses so clients can try another if one fails.
If nothing comes back, work through the header line instead, which +short hides. Run it again without +short and read the status: word:
| Status | Means |
|---|---|
NOERROR with answers | working |
NOERROR, ANSWER: 0 | the name exists but has no record of that type |
NXDOMAIN | the name does not exist |
SERVFAIL | the resolver tried and failed, often DNSSEC, see dnssec-troubleshooting. If the answer carries an EDE: line, it already names the cause (extended-dns-errors) |
REFUSED | the resolver will not serve you, usually an access list |
timed out | nothing reachable at that address |
Step 3: is it telling you the truth?#
A resolver that answers is not necessarily a resolver that is honest. The test is to ask several and compare.
for r in 1.1.1.1 8.8.8.8 9.9.9.9; do
echo "$r -> $(dig @"$r" +short isitdns.net A | tr '\n' ' ')"
doneWhat you want: the same set of addresses from each, allowing for order changes and for large services that legitimately vary by location.
Know your vantage before you trust any of this. Every command above leaves on UDP port 53, and plenty of home routers, hotel networks, and corporate gateways intercept port 53 and answer in the resolver's name. When that happens
dig @1.1.1.1is not talking to Cloudflare at all, it is talking to the box in the hallway, and the giveaway is usually a strippedadflag. Confirm over an encrypted transport, which the interceptor cannot forge:dig @1.1.1.1 +https +dnssec isitdns.net AIf
+httpsshowsadand the plain UDP query does not, something on your path is answering for the resolver. Never report an intercepted answer as the resolver's own. See dot-doh.
If one differs sharply, especially by returning a single address on a private range like 192.168.x.x or 10.x.x.x when the others return public addresses, that resolver is rewriting answers. That can be deliberate (split horizon, parental filtering, enterprise blocking) or hostile.
If all three agree with each other but disagree with what you get without @, the thing rewriting answers is between you and all of them. See the interception check on the troubleshooting index.
Step 4: is it a resolver at all?#
Two different jobs get confused constantly. A resolver does the lookup work for you: RFC 1034 §2.4 calls resolvers "programs that extract information from name servers in response to client requests", and §5.1 adds that they "interface user programs to domain name servers". An authoritative server owns a zone and answers only for that zone. Pointing at the wrong kind produces confusing failures.
dig @1.1.1.1 isitdns.net SOACheck the flags line:
rapresent means recursion available: this is a resolver and it will do work for youaapresent means authoritative: this server owns the zone the name is in. It says nothing about whether the server also recurses; a server that does both setsaafor its own zones and answers everything else like any other resolver. Readrafor the recursion question andaafor the ownership one
A machine configured to use an authoritative-only server as its resolver can look up names in that one zone and nothing else. It is a strange, memorable failure once you have seen it. Details in query-types.
Step 5: is it caching something stale?#
Caching is why "it works for me" and "it is broken for me" can both be true at the same moment.
Ask twice and watch the TTL:
dig @1.1.1.1 isitdns.net A | grep -E "^isitdns"Run it again a few seconds later. The number in the second column is the TTL, in seconds.
- counting down between runs: you are being served from cache, and the answer is that many seconds from expiring
- back at its full value: the cache expired and the resolver went and got a fresh copy
If you just changed a record and are still seeing the old value, compare against the authority directly, which has no cache in front of it. That is check-an-auth.
Quick reference#
| Symptom | Where to look |
|---|---|
| nothing resolves at all | step 1, you may be pointed at the wrong server |
| one name is wrong, others fine | step 5, caching, then check-an-auth |
| answers differ between resolvers | step 3, something is rewriting |
| works in terminal, not in browser | browser has its own DNS, see dot-doh |
| only names in one zone resolve | step 4, that is an authoritative server |
SERVFAIL on one specific name | extended-dns-errors first, then dnssec-troubleshooting |
See also#
- query-types: recursive versus authoritative, and what
rdandramean - check-a-forwarder: when your resolver hands queries onward
- extended-dns-errors: reading the
EDE:line a resolver attaches to a failure - nslookup-and-dig: tool comparison
- anatomy-of-a-query: the full journey of one lookup