This error occurs when Node.js cannot resolve a hostname to an IP address through DNS. It typically happens when making HTTP requests to domains that don't exist, are misspelled, or when DNS resolution fails due to network connectivity issues.
The ENOTFOUND error in Node.js indicates that the DNS (Domain Name System) resolution failed for a given hostname. When Node.js tries to make a network request using modules like http, https, axios, or fetch, it must first translate the domain name into an IP address through DNS lookup. The underlying system call getaddrinfo() is used for this resolution, and when it fails to find the hostname, it returns the ENOTFOUND error code. This error will occur not only when the hostname doesn't exist, but also when DNS lookup fails in other ways, such as no available file descriptors, network connectivity issues, DNS server problems, or firewall restrictions blocking DNS queries. Node's HTTP clients (including the native HTTP module and libraries like axios) use dns.lookup() by default, which ultimately calls the system's getaddrinfo() function. If a response isn't received from the DNS server within approximately 3500ms, Node.js will return this error.
First, check that your hostname doesn't contain typos or extra characters. Ensure you're using only the domain name without protocol or port.
// ❌ Incorrect - includes protocol
const options = {
host: 'https://api.example.com',
port: 443,
path: '/data'
};
// ✅ Correct - only domain name
const options = {
host: 'api.example.com',
port: 443,
path: '/data'
};Test if the domain resolves using the command line:
# Test DNS resolution
nslookup example.com
# Or use dig for more details
dig example.comVerify your machine has internet access and can reach DNS servers:
# Test internet connectivity
ping 8.8.8.8
# Test DNS resolution to a known domain
ping google.com
# Check your DNS server configuration
cat /etc/resolv.confIf connectivity is the issue, check your network settings or contact your network administrator.
Add error handling to prevent your application from crashing:
const https = require('https');
https.get('https://example.com', (res) => {
console.log('Status:', res.statusCode);
}).on('error', (err) => {
if (err.code === 'ENOTFOUND') {
console.error('DNS lookup failed:', err.hostname);
// Implement retry logic or fallback behavior
} else {
console.error('Request error:', err);
}
});With axios:
const axios = require('axios');
try {
const response = await axios.get('https://example.com');
console.log(response.data);
} catch (error) {
if (error.code === 'ENOTFOUND') {
console.error('DNS resolution failed for:', error.hostname);
// Handle DNS error gracefully
} else {
console.error('Request failed:', error.message);
}
}If you're getting ENOTFOUND for localhost, check your /etc/hosts file (or C:\Windows\System32\drivers\etc\hosts on Windows):
# View hosts file on Linux/macOS
cat /etc/hosts
# Ensure these lines exist:
127.0.0.1 localhost
::1 localhostIf the mappings are missing, add them:
# On Linux/macOS (requires sudo)
sudo nano /etc/hosts
# On Windows (run as Administrator)
notepad C:\Windows\System32\drivers\etc\hostsAfter editing, flush your DNS cache:
# macOS
sudo dscacheutil -flushcache
sudo killall -HUP mDNSResponder
# Windows
ipconfig /flushdns
# Linux (systemd-resolved)
sudo systemd-resolve --flush-cachesTry switching to public DNS servers like Google DNS or Cloudflare:
On macOS:
# Add Google DNS
sudo networksetup -setdnsservers Wi-Fi 8.8.8.8 8.8.4.4
# Or use Cloudflare DNS
sudo networksetup -setdnsservers Wi-Fi 1.1.1.1 1.0.0.1On Linux (using systemd-resolved):
# Edit resolved.conf
sudo nano /etc/systemd/resolved.conf
# Add these lines:
[Resolve]
DNS=8.8.8.8 8.8.4.4
FallbackDNS=1.1.1.1 1.0.0.1
# Restart the service
sudo systemctl restart systemd-resolvedOn Windows:
Open Network Connections → Adapter Properties → Internet Protocol Version 4 → Properties → Use the following DNS server addresses:
- Preferred: 8.8.8.8
- Alternate: 8.8.4.4
If DNS resolution continues to fail, you can temporarily use the IP address directly:
const https = require('https');
// Find the IP address first
// nslookup example.com → 93.184.216.34
const options = {
host: '93.184.216.34',
port: 443,
path: '/api/endpoint',
headers: {
'Host': 'example.com' // Important: Include original hostname in headers
}
};
https.get(options, (res) => {
console.log('Connected using IP address');
});Note: This is a temporary workaround. The IP address may change, and HTTPS certificates will validate against the hostname, not the IP.
For applications making many requests, enable connection reuse and DNS caching to reduce DNS lookup frequency:
const http = require('http');
const https = require('https');
// Create agents with keepAlive enabled
const httpAgent = new http.Agent({
keepAlive: true,
keepAliveMsecs: 10000,
maxSockets: 50
});
const httpsAgent = new https.Agent({
keepAlive: true,
keepAliveMsecs: 10000,
maxSockets: 50
});
// Use with axios
const axios = require('axios');
const client = axios.create({
httpAgent,
httpsAgent
});
// Or with fetch (Node 18+)
fetch('https://example.com', {
agent: httpsAgent
});For even better DNS caching, consider using a DNS cache library:
const https = require('https');
const CacheableLookup = require('cacheable-lookup');
const cacheable = new CacheableLookup();
cacheable.install(https.globalAgent);
// Now all https requests will use cached DNSDNS Resolution Methods in Node.js
Node.js provides two DNS resolution methods with different behaviors:
- dns.lookup(): Uses the system's getaddrinfo() function, which reads /etc/hosts and respects system DNS configuration. This is what HTTP modules use by default. It has a timeout of approximately 3500ms.
- dns.resolve(): Directly queries DNS servers, bypassing /etc/hosts. It's faster but won't respect system-level host overrides.
You can configure Node.js HTTP clients to use dns.resolve() instead:
const dns = require('dns');
const { Resolver } = dns;
const resolver = new Resolver();
resolver.setServers(['8.8.8.8', '1.1.1.1']);
// Custom lookup function
function customLookup(hostname, options, callback) {
resolver.resolve4(hostname, (err, addresses) => {
if (err) return callback(err);
callback(null, addresses[0], 4);
});
}
// Use with http.request
const options = {
host: 'example.com',
lookup: customLookup
};SNAT Port Exhaustion
In cloud environments (Azure, AWS, etc.), making many concurrent requests without connection reuse can cause SNAT (Source Network Address Translation) port exhaustion, which manifests as ENOTFOUND errors. Each new connection requires DNS resolution and a new port. The solution is enabling keep-alive and connection pooling.
Firewall and VPN Issues
Corporate firewalls and VPNs often intercept or block DNS traffic. If you experience this error only on certain networks:
1. Check if your firewall allows outbound UDP traffic on port 53
2. Try using DNS over HTTPS (DoH) which uses port 443
3. Contact your IT department to whitelist the domains you need
Docker and Container Networking
In Docker containers, DNS resolution depends on the container's network configuration. If you see ENOTFOUND in containers:
- Check the container's /etc/resolv.conf
- Ensure the Docker daemon's DNS settings are correct
- Use --dns 8.8.8.8 flag when running containers
- Consider using host networking mode: --network host
Error: Listener already called (once event already fired)
EventEmitter listener already called with once()
Error: EACCES: permission denied, open '/root/file.txt'
EACCES: permission denied
Error: Invalid encoding specified (stream encoding not supported)
How to fix Invalid encoding error in Node.js readable streams
Error: EINVAL: invalid argument, open
EINVAL: invalid argument, open
TypeError: readableLength must be a positive integer (stream config)
TypeError: readableLength must be a positive integer in Node.js streams