MacOS High Sierra not trying other DNS servers

dnshigh sierramacos

On one of my laptops which is running macOS High Sierra, is failing to resolve hostnames. I have specified two DNS servers in my network settings. One is an internal DNS server, and the other is 8.8.8.8. When I try to resolve local hostnames that the internal DNS knows, it resolves properly. But when I try to resolve something like google.com it fails.

I see that it tries to use the internal DNS server first, and since it doesn't know the hostname, I thought it would try to use 8.8.8.8 to resolve the hostname, but it never tries the other DNS server.

When I try this from my other laptop, it works properly i see

$>nslookup google.com
;; Got SERVFAIL reply from <internal dns>, trying next server
Server:     8.8.8.8
Address:    8.8.8.8#53

Non-authoritative answer:
Name:   google.com
Address: 172.217.5.110

But from the one where it doesn't I see

$>nslookup google.com
Server:        <internal dns>
Address:    <internal dns>#53

** server can’t find google.com: SERVFAIL

There is no attempt to try the 8.8.8.8 DNS server. Why is that happening? How can I get it to try the other DNS server if it fails with one.

Best Answer

First: nslookup does not use the system DNS resolver, and does not behave the same way that the system resolver does. Neither do dig or host, so none of these tools are useful for checking how macOS resolves names. If you want to use the system resolver, use dscacheutil -q host -a name google.com, but note that it uses the entire resolution system -- it looks in the local cache, /etc/hosts, mDNS (for .local names), and then DNS. Oh, and the man page for dscacheutil claims it can flush the DNS cache, but it doesn't work; use sudo killall mDNSResponder instead.

Second: the system resolver does not do a good (or even adequate) job of failing over between DNS servers. If you list multiple servers, it'll fire off queries to all of them in a sort of randomized-round-robin fashion. If it doesn't get a response, it'll eventually time out and try the other one. If it gets a "that doesn't exist" response, it assumes that's correct and doesn't try any other server. As a result, you really need a single server that can answer all queries, both internal and external.

Ok, there's one possible workaround: you can point your system at a public DNS server, then create /etc/resolver/ and put files in it to redirect queries for certain domains to your internal server. Provided you know what domains to redirect, that is. See Apple.SE: "Do /etc/resolver/ files work in Mountain Lion for DNS resolution?".