How to fix Error: SERVFAIL (DNS server returned SERVFAIL) in Node.js
This error occurs when a DNS server fails to complete a hostname lookup in Node.js. It typically indicates DNS server configuration issues, DNSSEC validation failures, or network connectivity problems between your application and the DNS resolver.
Quick fix
Fixes SERVFAIL
# Check DNS server connectivity (Linux/macOS)
nslookup google.com
dig google.com
# Test specific DNS server
nslookup google.com 8.8.8.8
dig @8.8.8.8 google.com
# Windows
nslookup google.com- Verify the DNS server is reachable
- Switch to alternative DNS servers
- Change system DNS configuration
- Implement DNS caching and retry logic
# Check DNS server connectivity (Linux/macOS)nslookup google.comdig google.com# Test specific DNS servernslookup google.com 8.8.8.8dig @8.8.8.8 google.com# Windowsnslookup google.comError: SERVFAIL (DNS server returned SERVFAIL)
What this error means
The SERVFAIL error (Server Failure) is a DNS response code that indicates the DNS server encountered a general failure while attempting to resolve a hostname. In Node.js, this error surfaces when using DNS methods like `dns.lookup()`, `dns.resolve()`, or when making HTTP requests that require hostname resolution. When Node.js performs a DNS lookup, it queries configured DNS servers to translate domain names into IP addresses. A SERVFAIL response means the DNS server received the query but couldn't provide a valid answer due to internal errors, misconfigurations, or upstream issues. Unlike ENOTFOUND (hostname doesn't exist), SERVFAIL indicates the DNS infrastructure itself has a problem. This error is particularly common in containerized environments, corporate networks with strict DNS policies, or when dealing with DNSSEC-enabled domains where signature validation fails. The error code is standardized across DNS implementations, so Node.js simply surfaces what the underlying DNS resolver reports.
Typical symptoms
- DNS lookups fail with "Error: queryA SERVFAIL" or similar messages
- HTTP requests to external APIs fail immediately with SERVFAIL errors
- Application works on some networks but fails on others with DNS errors
- Intermittent failures where some domains resolve while others return SERVFAIL
- Error stack traces showing dns.js or resolver-related failures
Common causes
- DNS server is overloaded or experiencing technical issues
- DNSSEC validation failures due to invalid or missing signatures
- Misconfigured DNS records on the authoritative name server
- Network connectivity issues between the resolver and authoritative DNS server
- Firewall or security group blocking DNS traffic on port 53
- DNS forwarder timeout before receiving a response from upstream servers
- Corrupted DNS cache on the DNS server
- Recursive query failures when the DNS server cannot contact authoritative servers
How to fix "Error: SERVFAIL (DNS server returned SERVFAIL)"
Check if your configured DNS servers are accessible and responding:
# Check DNS server connectivity (Linux/macOS)
nslookup google.com
dig google.com
# Test specific DNS server
nslookup google.com 8.8.8.8
dig @8.8.8.8 google.com
# Windows
nslookup google.comIf queries to public DNS servers (like 8.8.8.8 or 1.1.1.1) work but your default DNS fails, the issue is with your configured DNS server.
Configure Node.js to use reliable public DNS servers using the dns.setServers() method:
const dns = require('dns');
// Use Google Public DNS
dns.setServers(['8.8.8.8', '8.8.4.4']);
// Or Cloudflare DNS
// dns.setServers(['1.1.1.1', '1.0.0.1']);
// Test the resolution
dns.resolve('example.com', (err, addresses) => {
if (err) {
console.error('DNS resolution failed:', err);
} else {
console.log('Resolved addresses:', addresses);
}
});Important: dns.setServers() only affects dns.resolve() and related methods, not dns.lookup() which uses the OS resolver. For dns.lookup(), you must change system DNS settings.
If using dns.lookup() or making HTTP requests, modify your system's DNS settings:
Linux (/etc/resolv.conf):
sudo nano /etc/resolv.confAdd or modify nameserver entries:
nameserver 8.8.8.8
nameserver 8.8.4.4macOS:
# Temporary change
sudo networksetup -setdnsservers Wi-Fi 8.8.8.8 8.8.4.4
# Revert to DHCP
sudo networksetup -setdnsservers Wi-Fi emptyWindows (PowerShell as Administrator):
Set-DnsClientServerAddress -InterfaceAlias "Ethernet" -ServerAddresses 8.8.8.8,8.8.4.4Docker containers:
Add DNS servers to docker-compose.yml:
services:
app:
dns:
- 8.8.8.8
- 8.8.4.4Add resilience to your application with caching and retries:
const dns = require('dns').promises;
async function resolveWithRetry(hostname, retries = 3, delay = 1000) {
for (let i = 0; i < retries; i++) {
try {
const addresses = await dns.resolve4(hostname);
return addresses;
} catch (error) {
if (error.code === 'SERVFAIL' && i < retries - 1) {
console.log(`DNS SERVFAIL for ${hostname}, retry ${i + 1}/${retries}`);
await new Promise(resolve => setTimeout(resolve, delay));
continue;
}
throw error;
}
}
}
// Usage
resolveWithRetry('example.com')
.then(addresses => console.log('Resolved:', addresses))
.catch(err => console.error('Failed after retries:', err));For HTTP requests, use a library with built-in DNS caching like cacheable-lookup:
npm install cacheable-lookupconst http = require('http');
const CacheableLookup = require('cacheable-lookup');
const cacheable = new CacheableLookup();
cacheable.install(http.globalAgent);
// Now all http requests use cached DNS lookupsDNSSEC failures often cause SERVFAIL errors. Test DNSSEC validation:
# Check DNSSEC status
dig +dnssec example.com
# Test with DNSSEC validation disabled
dig +cd example.comIf +cd (checking disabled) succeeds but regular queries fail, DNSSEC is the issue.
Disable DNSSEC validation in Node.js (not recommended for production):
// Use dns.resolve() with custom resolver that doesn't validate DNSSEC
const { Resolver } = require('dns');
const resolver = new Resolver();
resolver.setServers(['8.8.8.8']); // Use a resolver without strict DNSSEC
resolver.resolve4('example.com', (err, addresses) => {
console.log(addresses);
});Better solution: Contact the domain administrator to fix DNSSEC signatures.
Ensure DNS traffic (UDP/TCP port 53) is allowed:
# Test UDP DNS (most common)
nc -vuz 8.8.8.8 53
# Test TCP DNS (used for large responses)
nc -vz 8.8.8.8 53
# Check if DNS queries are being blocked
sudo tcpdump -i any port 53AWS environments: Check security groups and NACLs allow outbound UDP/TCP port 53.
Corporate networks: Some organizations block external DNS. Contact IT to whitelist your application or use internal DNS servers.
Docker: Verify DNS settings in /etc/docker/daemon.json:
{
"dns": ["8.8.8.8", "8.8.4.4"]
}Advanced notes
DNS Resolver Differences in Node.js:
Node.js provides two DNS resolution mechanisms:
- dns.lookup(): Uses the OS's getaddrinfo() function, respects /etc/hosts, and cannot be configured via dns.setServers()
- dns.resolve(), dns.resolve4(), dns.resolve6(): Performs actual DNS queries, can be configured with dns.setServers(), bypasses /etc/hosts
HTTP modules like http and https use dns.lookup() by default, which is why dns.setServers() doesn't affect them.
AWS Route 53 SERVFAIL Issues:
In AWS environments, SERVFAIL responses often occur when:
- Route 53 Resolver outbound endpoints cannot reach on-premises DNS servers
- VPC DNS resolver IPs are blocked by third-party DNS providers
- Name server configurations in parent/child hosted zones don't match
Solution: Ensure security group egress rules allow UDP/TCP 53 to target IPs, and verify network ACLs.
DNSSEC and SERVFAIL:
DNSSEC adds cryptographic signatures to DNS records. Common DNSSEC-related SERVFAIL causes:
- Expired DNSSEC signatures (RRSIG records)
- Missing DS records in the parent zone
- Clock skew causing signature validation failures
- Key rollover errors
Use tools like dnsviz.net to visualize DNSSEC validation chains and identify signature issues.
Debugging in Production:
For production debugging without changing system DNS:
const { Resolver } = require('dns').promises;
async function debugDNS(hostname) {
const resolvers = [
{ name: 'Google', servers: ['8.8.8.8', '8.8.4.4'] },
{ name: 'Cloudflare', servers: ['1.1.1.1', '1.0.0.1'] },
{ name: 'System Default', servers: null }
];
for (const { name, servers } of resolvers) {
const resolver = servers ? new Resolver() : new Resolver();
if (servers) resolver.setServers(servers);
try {
const result = await resolver.resolve4(hostname);
console.log(`${name}: SUCCESS -`, result);
} catch (error) {
console.log(`${name}: FAILED -`, error.code);
}
}
}
debugDNS('example.com');Frequently asked questions
- What does "SERVFAIL" mean?
- The SERVFAIL error (Server Failure) is a DNS response code that indicates the DNS server encountered a general failure while attempting to resolve a hostname. resolve(), or when making HTTP requests that require hostname resolution. js performs a DNS lookup, it queries configured DNS servers to translate domain names into IP addresses.
- How do I fix "SERVFAIL"?
- This error occurs when a DNS server fails to complete a hostname lookup in Node.js. It typically indicates DNS server configuration issues, DNSSEC validation failures, or network connectivity problems between your application and the DNS resolver.
- What causes "SERVFAIL"?
- DNS server is overloaded or experiencing technical issues DNSSEC validation failures due to invalid or missing signatures Misconfigured DNS records on the authoritative name server
- Is the "SERVFAIL" error serious?
- Yes. This is a high-severity error that usually blocks work until it is fixed, but the steps above resolve it.
Official resources & further reading
- ๐Node.js Official Documentation
- ๐
- ๐
- ๐
- ๐
- ๐github.com - 40717(GitHub)