This error occurs when Node.js attempts to establish a TCP connection but the operating system cannot find a network route to the destination. The connection fails because no routing path exists between your system and the target host.
The ENETUNREACH (Network Unreachable) error indicates that a TCP connection attempt has failed because the operating system cannot determine any route to reach the destination network or host. This is a low-level network error reported by the OS networking stack to Node.js. When Node.js makes outbound HTTP/HTTPS requests, connects to databases, or performs other network operations, it relies on the operating system's routing tables to determine how to reach the destination IP address. If no route exists—due to network configuration issues, firewall rules, or intermediate gateway problems—the OS returns ENETUNREACH (errno 101 on Linux systems). This error is distinct from EHOSTUNREACH (host unreachable) and ETIMEDOUT (connection timeout). ENETUNREACH specifically means the network layer cannot find any path to the destination, typically failing immediately rather than timing out after repeated attempts.
First, check if you can reach the destination host using system networking tools:
# Ping the target host
ping example.com
# Check routing table
ip route show # Linux
route print # Windows
netstat -rn # macOS
# Test TCP connection directly
telnet example.com 443
# or
nc -zv example.com 443If ping or telnet fails, the issue is at the OS networking level, not specific to Node.js.
If you're connecting to resources that require VPN access, ensure your VPN is active:
# Check VPN interface is up (Linux/macOS)
ifconfig | grep tun
ip addr show tun0
# Verify VPN routes are present
ip route | grep vpnReconnect to your VPN if disconnected, then retry the Node.js operation.
If the error shows an IPv6 address (containing colons like 2606:4700::...) but your system doesn't have IPv6 routing:
// Force IPv4 for HTTP requests
const https = require('https');
const options = {
hostname: 'example.com',
port: 443,
path: '/',
method: 'GET',
family: 4 // Force IPv4
};
https.request(options, (res) => {
// Handle response
}).end();For axios:
const axios = require('axios');
axios.get('https://example.com', {
httpAgent: new (require('http').Agent)({ family: 4 }),
httpsAgent: new (require('https').Agent)({ family: 4 })
});For npm, configure registry to use IPv4:
npm config set registry https://registry.npmjs.org/
npm config set fetch-retries 3If you're behind a corporate proxy, configure Node.js and npm to use it:
# Set npm proxy
npm config set proxy http://proxy.company.com:8080
npm config set https-proxy http://proxy.company.com:8080
# Set environment variables for Node.js
export HTTP_PROXY=http://proxy.company.com:8080
export HTTPS_PROXY=http://proxy.company.com:8080
# For git operations via npm
git config --global http.proxy http://proxy.company.com:8080
git config --global https.proxy http://proxy.company.com:8080Include credentials if required:
npm config set proxy http://username:[email protected]:8080Verify that firewall rules aren't blocking outbound connections:
# Linux: Check iptables rules
sudo iptables -L -n
# Check if specific port is allowed
sudo iptables -L OUTPUT -n | grep 443
# Temporarily disable firewall for testing (Linux)
sudo systemctl stop firewalld # Fedora/CentOS
sudo ufw disable # UbuntuOn Windows, check Windows Defender Firewall and any third-party security software (Kaspersky, Norton, etc.). Add Node.js and npm to firewall exceptions if needed.
If running in Docker and can't reach external networks:
# Use host network mode
docker run --network host your-image
# Or ensure bridge network has proper routing
docker network inspect bridgeIn docker-compose.yml:
services:
app:
image: node:18
network_mode: "host"
# or
dns:
- 8.8.8.8
- 8.8.4.4Restart Docker networking:
sudo systemctl restart dockerImplement retry logic to handle temporary network unreachability:
const https = require('https');
function requestWithRetry(options, maxRetries = 3) {
return new Promise((resolve, reject) => {
let attempts = 0;
function attempt() {
attempts++;
const req = https.request(options, (res) => {
resolve(res);
});
req.on('error', (err) => {
if (err.code === 'ENETUNREACH' && attempts < maxRetries) {
console.log(`Retry attempt ${attempts} after ENETUNREACH`);
setTimeout(attempt, 1000 * attempts); // Exponential backoff
} else {
reject(err);
}
});
req.end();
}
attempt();
});
}IPv6 vs IPv4 Considerations: Many ENETUNREACH errors occur when DNS returns both IPv6 (AAAA) and IPv4 (A) records, but the system lacks IPv6 routing. Node.js may attempt IPv6 first and fail immediately. Setting family: 4 in connection options forces IPv4 usage.
VPN Split Tunneling: With split-tunnel VPN configurations, only specific routes go through the VPN. ENETUNREACH occurs when applications try to reach VPN-only resources while disconnected. Full-tunnel VPNs may avoid this by routing all traffic through the VPN gateway.
Error Handling Limitations: In some Node.js versions (notably 7.10.0), ENETUNREACH errors may not be catchable via standard error event handlers on sockets, instead throwing uncaught exceptions. Always test error handling thoroughly and consider process-level uncaughtException handlers.
Routing Table Debugging: Use traceroute (Linux/macOS) or tracert (Windows) to identify where routing fails. If the first hop fails, the issue is local routing. If it fails midway, it's an intermediate network problem.
Docker DNS Issues: Docker containers may encounter ENETUNREACH when the host's DNS resolver returns unreachable IP addresses. Explicitly setting DNS servers (--dns 8.8.8.8) can resolve this.
Corporate Network Environments: Some corporate networks use transparent proxies that intercept traffic. ENETUNREACH may indicate the proxy is unreachable or misconfigured. Contact your network administrators for proxy configuration details.
Error: EMFILE: too many open files, watch
EMFILE: fs.watch() limit exceeded
Error: Middleware next() called multiple times (next() invoked twice)
Express middleware next() called multiple times
Error: Worker failed to initialize (worker startup error)
Worker failed to initialize in Node.js
Error: EMFILE: too many open files, open 'file.txt'
EMFILE: too many open files
Error: cluster.fork() failed (cannot create child process)
cluster.fork() failed - Cannot create child process