An application intermittently fails to resolve a hostname — most requests succeed, but a small percentage fail with a DNS error. How would you track this down?
Short Answer
Capture the actual failing resolutions rather than reasoning about it abstractly — tcpdump or dig in a tight loop against the same resolver the application uses will usually surface either UDP packet loss/timeout to the resolver, a resolver returning SERVFAIL/NXDOMAIN intermittently, or (very commonly in containerized environments) the classic Linux glibc resolver behavior of racing parallel A/AAAA queries and mishandling one of them under specific timing. The failure pattern (does it correlate with load, with a specific resolver, with IPv6) narrows it fast once you're looking at real packets instead of guessing.
Detailed Explanation
Intermittent DNS failures are frustrating precisely because DNS resolution is usually invisible — applications call a name resolution library function and get an IP back, with no logging of the resolver interaction unless you specifically capture it. The investigation has to start by making that interaction visible: either packet capture between the application host and its configured resolver, or a scripted loop calling dig/getent hosts repeatedly against the exact same resolver configuration the application uses, watching for the failures to reproduce.
A few specific, well-known causes are worth checking first because they're common and have a recognizable signature. UDP-based DNS queries can be silently dropped under network congestion or by a stateful firewall/NAT with an aggressive UDP conntrack timeout, especially under load — this shows as occasional timeouts correlating with traffic spikes. In containerized environments (Docker, Kubernetes), a well-documented glibc behavior sends A and AAAA queries in parallel over the same UDP socket for IPv6-enabled systems, and a race in how the responses are matched up (particularly with musl libc, or specific glibc/kernel/conntrack combinations) can cause one of the two queries to silently fail, surfacing as intermittent resolution errors that are hard to reproduce outside the exact environment. It's also worth checking whether the failures correlate with a specific one of multiple configured resolvers (in /etc/resolv.conf) — if there are two resolvers listed and one of them is subtly broken or overloaded, glibc's fallback behavior between them isn't always as clean as expected.
Symptoms
- A small, roughly consistent percentage of DNS lookups fail; the majority succeed.
- The application-level error is generic ("could not resolve host," a connection timeout, or similar) without further DNS-specific detail.
- The failure doesn't correlate obviously with a specific hostname, time of day, or an obvious external event.
Possible Causes
- UDP DNS query packet loss between the application host and its resolver, often correlating with network load or an aggressive NAT/firewall conntrack timeout for UDP.
- The
glibcparallel A/AAAA query race condition, common in containerized/Kubernetes environments where IPv6 is enabled at the resolver layer but not fully used. - One of multiple configured resolvers (in
/etc/resolv.confor the container's DNS config) being intermittently slow or unreliable, with imperfect fallback behavior to the working one. - The resolver itself (e.g. a cluster's internal DNS service like CoreDNS) being under-provisioned and occasionally timing out or dropping queries under load.
- A caching resolver returning a stale or incorrect negative-cache entry for a hostname that recently changed.
Investigation Steps
- Identify exactly which resolver(s) the application is configured to use (
/etc/resolv.conf, or the container/pod's DNS config). - Run a tight loop of
dig/getent hostsagainst that exact hostname and resolver, logging failures, to reproduce the issue outside the application. - If reproducible, run
tcpdump -i any port 53(or-i any port 53 or port 5353if applicable) during the loop to capture the actual query/response traffic and see whether queries are being sent with no response, or a response is coming back with an error code. - Check whether failures correlate with load (CPU/network) on the application host, or with load on the resolver itself (e.g. CoreDNS metrics in a Kubernetes cluster).
- If in a containerized environment with IPv6 partially configured, check for the known
glibcparallel-query race — a quick test is disabling IPv6 lookups (or settingsingle-requestin/etc/resolv.conf'soptions) and seeing if the failure rate changes. - Check the resolver's own logs/metrics for error rates, timeouts, or resource exhaustion during the failure window.
Commands
cat /etc/resolv.conf
for i in $(seq 1 200); do dig +short example.com @<resolver-ip> || echo "FAIL $i"; done
sudo tcpdump -i any port 53 -w dns-capture.pcap
Resolution
If it's UDP packet loss or conntrack-related, the fix is usually infrastructure-level: increasing conntrack table size/timeout, or addressing whatever's causing network congestion at the times failures cluster. If it's the glibc parallel-query race, adding options single-request (or single-request-reopen) to resolv.conf forces sequential rather than parallel A/AAAA queries, which is the well-documented workaround. If it's an under-provisioned cluster resolver, scale it (more CoreDNS replicas, adjusted resource limits) or add local caching (e.g. node-local-dns in Kubernetes) to reduce the query volume actually hitting the central resolver.
Prevention
- Add DNS resolution latency and error-rate monitoring at the resolver level, not just inferred from application-level symptoms.
- In Kubernetes specifically, consider a local DNS cache (NodeLocal DNSCache) to reduce load on cluster DNS and reduce the blast radius of any single resolver having a bad moment.
- Set
options single-requestproactively in environments known to be affected by the glibc parallel-query issue, rather than waiting to hit it in production. - Load-test DNS resolution specifically (not just application throughput) before assuming a new environment's DNS setup will hold up under real traffic.
Interview Follow-Up Questions
- Why does DNS primarily use UDP instead of TCP, and what are the tradeoffs of that choice for reliability?
- How does
NodeLocal DNSCachein Kubernetes actually reduce DNS-related failures, mechanically? - How would you differentiate a client-side resolution problem from the authoritative/upstream DNS server itself being unreliable?
Key Takeaways
- Intermittent DNS failures need to be made visible via packet capture or reproduction, not reasoned about abstractly.
- UDP packet loss and the glibc parallel A/AAAA query race are the two most common, well-documented causes worth checking first.
- Correlate failures against load (both application host and resolver) as a fast way to narrow the cause.
options single-requestinresolv.confis a known, specific fix for one common failure mode — not a universal fix for all DNS intermittency.
References
Last updated August 21, 2026 · Last reviewed August 21, 2026