Why would `dig` succeed, but `host`, `nslookup`, `curl`, `ping` all fail?

host and nslookup make several separate DNS queries – one for each record type. They want to show you both IPv4 and IPv6 addresses, so they need to make an A query and an AAAA query.

If you run host -v api.nordvpn.com (with the 'verbose' option to show responses in dig-like format), you will see that it is actually equivalent to these 3 commands in a row:

dig api.nordvpn.com A
dig api.nordvpn.com AAAA
dig api.nordvpn.com MX

Running nslookup -debug api.nordvpn.com will similarly show it querying for both A and AAAA records (although not MX).

If you look carefully at your Docker output, you will notice that the A query actually succeeds, it's the AAAA one which returns a SERVFAIL. So the failure is never visible in 'dig' because you never asked it to make AAAA queries.

There could be several explanations for the partially failing queries:

  • Your resolver has some connectivity issues with the authoritative servers, but it happens to have results for A cached from earlier and is still able to return those.

  • The authoritative servers of nordvpn.com are returning responses for A queries but failing to respond at all for AAAA queries.

  • Your DNS requests are being intercepted and redirected to a different resolver, and that resolver blocks all AAAA queries under the pretense of "not supporting IPv6" or "avoiding IPv6 VPN leaks" or similar.

Indeed your dig +trace output already shows that it's the 3rd case:

api.nordvpn.com.    299 IN  A   104.17.50.74
api.nordvpn.com.    299 IN  A   104.17.49.74
;; Received 106 bytes from 199.7.83.42#53(l.root-servers.net) in 43 ms

In trace mode, dig starts by contacting the root servers, where it's supposed to receive a referral response (one that points to the '.com' servers) and follow the chain.

But in your case, dig somehow immediately receives a direct answer with the requested A records. That's not how the root servers work – they are not able to provide such answers. The only time you would see this result is if your packets on port 53 are being redirected to a local resolver and you're not, in fact, talking to the DNS server that you think you're talking to.


Try making a DNS query at 192.0.2.1 or 203.0.113.1 – if you receive a response from this address you'll know it's not legitimate, because this address does not exist anywhere on the Internet.)

dig @192.0.2.1 google.com

Try making these queries to find out the name of the DNS server that you're actually talking to:

dig @9.9.9.9 hostname.bind chaos txt
dig @9.9.9.9 id.server chaos txt

(If talking to the real 9.9.9.9, you should see something like "res600.fra.rrdns.pch.net" as the id.server response.)

It might be worth trying to traceroute --udp --port=53 9.9.9.9; it will show normal results until it reaches the point where the packets are being redirected, nonsensical results afterwards.