Negative DNS caching occurs when a DNS server stores the absence of a record (NXDOMAIN response) to prevent redundant queries. While RFC 1034 doesn't mandate specific TTL values, real-world implementations follow these patterns:
// Example BIND9 negative cache configuration (named.conf)
options {
// Default negative caching TTL (in seconds)
max-ncache-ttl 3600; // 1 hour
// Minimum negative cache TTL
min-ncache-ttl 1800; // 30 minutes
};
Major DNS implementations use these defaults:
- BIND9: 3600 seconds (1 hour)
- Unbound: 60 seconds (configurable via
cache-min-ttl
) - Windows DNS: 300 seconds (5 minutes)
- PowerDNS: Inherits SOA minimum TTL or 3600s
When implementing DNS clients, you can override default negative caching:
# Python dnspython example
import dns.resolver
resolver = dns.resolver.Resolver()
resolver.cache = dns.resolver.LRUCache() # Local negative caching
resolver.cache.flush() # Manual cache invalidation
# Go's net/http with custom DNS client
package main
import (
"net/http"
"time"
"golang.org/x/net/http/httpproxy"
)
func main() {
transport := &http.Transport{
Proxy: httpproxy.FromEnvironment(),
DialContext: (&net.Dialer{
Timeout: 30 * time.Second,
KeepAlive: 30 * time.Second,
DualStack: true,
// Custom DNS cache TTL
Resolver: &net.Resolver{
PreferGo: true,
Dial: func(ctx context.Context, network, address string) (net.Conn, error) {
d := net.Dialer{Timeout: 10 * time.Second}
return d.DialContext(ctx, "udp", "8.8.8.8:53")
},
},
}).DialContext,
}
}
To verify negative caching behavior:
# Linux/macOS dig command
dig +nocmd +nocomments +noquestion +nostats example.com
# Windows nslookup
nslookup -d2 nonexistent.domain 2>&1 | findstr "negative cache"
# Cloudflare-specific check
curl -H "accept: application/dns-json" \
"https://1.1.1.1/dns-query?name=bad.domain&type=A" | jq '.Answer[].TTL'
For microservices architectures:
- Set negative cache TTL lower than service discovery intervals
- Implement circuit breakers for DNS failures
- Combine with HTTP caching headers when making API calls
// Java negative cache with Caffeine
LoadingCache> dnsCache = Caffeine.newBuilder()
.expireAfterWrite(5, TimeUnit.MINUTES) // Negative cache duration
.build(host -> {
try {
return Optional.of(InetAddress.getByName(host));
} catch (UnknownHostException e) {
return Optional.empty(); // Negative cache entry
}
});
When a DNS server encounters a non-existent domain (NXDOMAIN) response, it implements negative caching to prevent repeated lookups for the same non-existent record. This behavior isn't explicitly defined in RFC 1034, leading to implementation-specific TTL durations.
In practice, most DNS servers use these default negative cache TTLs:
- BIND: 5-30 minutes (configurable via
max-ncache-ttl
) - PowerDNS: 60 seconds to 1 hour
- Windows DNS: 15 minutes by default
- Google Public DNS: 300 seconds (5 minutes)
For BIND (named.conf):
options {
max-ncache-ttl 1800; // 30 minutes
max-cache-ttl 86400; // 1 day
};
For PowerDNS (pdns.conf):
default-soa-ttl=3600
default-soa-minimum=300
When developing applications that rely on DNS, consider these patterns:
// Python example with retry logic
import socket
import time
def resolve_host(hostname, retries=3):
for attempt in range(retries):
try:
return socket.gethostbyname(hostname)
except socket.gaierror:
if attempt == retries - 1:
raise
time.sleep(5 * (attempt + 1)) # Exponential backoff
Use these commands to check negative caching behavior:
# Linux/macOS
dig +norecurse example.com
dscacheutil -q host -a name nonexistent.domain
# Windows
nslookup -d2 nonexistent.domain
AWS Route 53 uses 300 seconds for negative caching, while Cloudflare offers configurable negative TTL through their dashboard with a default of 14400 seconds (4 hours).