is it DNS? wiki/Troubleshooting/How to check a resolver
Troubleshooting

🔎 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.conf

Look for the nameserver lines. That is who your machine asks.

On macOS:

scutil --dns | grep nameserver | head -5

On Windows, in PowerShell:

Get-DnsClientServerAddress -AddressFamily IPv4

A 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 +short

Swap 1.1.1.1 for your own resolver's IP. Real output:

104.21.56.211
172.67.155.242

Reading 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:

StatusMeans
NOERROR with answersworking
NOERROR, ANSWER: 0the name exists but has no record of that type
NXDOMAINthe name does not exist
SERVFAILthe resolver tried and failed, often DNSSEC, see dnssec-troubleshooting. If the answer carries an EDE: line, it already names the cause (extended-dns-errors)
REFUSEDthe resolver will not serve you, usually an access list
timed outnothing 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' ' ')"
done

What 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.1 is not talking to Cloudflare at all, it is talking to the box in the hallway, and the giveaway is usually a stripped ad flag. Confirm over an encrypted transport, which the interceptor cannot forge:

dig @1.1.1.1 +https +dnssec isitdns.net A

If +https shows ad and 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 SOA

Check the flags line:

  • ra present means recursion available: this is a resolver and it will do work for you
  • aa present 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 sets aa for its own zones and answers everything else like any other resolver. Read ra for the recursion question and aa for 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#

SymptomWhere to look
nothing resolves at allstep 1, you may be pointed at the wrong server
one name is wrong, others finestep 5, caching, then check-an-auth
answers differ between resolversstep 3, something is rewriting
works in terminal, not in browserbrowser has its own DNS, see dot-doh
only names in one zone resolvestep 4, that is an authoritative server
SERVFAIL on one specific nameextended-dns-errors first, then dnssec-troubleshooting

See also#