The ENETUNREACH error occurs when Node.js cannot establish a network connection because the destination network is unreachable. This typically indicates routing problems, network interface issues, or firewall restrictions preventing your application from reaching the target host.
The ENETUNREACH (Error Number 101) error is a low-level network error that occurs when the operating system's networking stack determines that no route exists to reach the destination network. This is different from a connection timeout or refused connection - the system knows immediately that it cannot even attempt to reach the target. When Node.js makes a network request using modules like `http`, `https`, `axios`, or `fetch`, it relies on the underlying operating system to establish the connection. If the OS cannot find a valid network path to the destination IP address or subnet, it returns the ENETUNREACH error. This error commonly appears in containerized environments (Docker, Kubernetes), when using VPNs, during network configuration changes, or when attempting to connect to private/internal networks from an isolated context.
First, confirm that the IP address you're trying to reach is correct and that basic network connectivity exists:
# Ping the target IP
ping 10.0.0.1
# Check if the IP is reachable
traceroute 10.0.0.1
# Verify your network interfaces are up
ip addr show
# or on older systems
ifconfigIf ping fails with "Network is unreachable", the problem is at the routing level, not specific to Node.js.
Examine your system's routing table to see if a route exists for the destination network:
# On Linux/Mac
ip route show
# or
route -n
# On Windows
route printLook for a route that matches the destination network. If missing, you may need to add a route:
# Add a route (requires sudo)
sudo ip route add 10.0.0.0/24 via 192.168.1.1 dev eth0Replace 10.0.0.0/24 with your destination network, 192.168.1.1 with your gateway, and eth0 with your network interface.
If you're running Node.js in a Docker container and experiencing this error, the issue often relates to network isolation or subnet conflicts:
Option 1: Use host network mode (removes network isolation)
# docker-compose.yml
services:
app:
image: node:18
network_mode: "host"Option 2: Configure Docker default address pools to avoid VPN/network conflicts:
// /etc/docker/daemon.json
{
"default-address-pools": [
{
"base": "172.17.0.0/12",
"size": 24
}
]
}After modifying daemon.json, restart Docker:
sudo systemctl restart dockerOption 3: Add route inside container (if you need specific network access):
# In your Dockerfile
RUN ip route add 10.0.0.0/24 via 172.17.0.1If containers need to reach external networks, ensure IP forwarding is enabled on the host:
# Check if IP forwarding is enabled
sysctl net.ipv4.ip_forward
# Enable IP forwarding temporarily
sudo sysctl -w net.ipv4.ip_forward=1
# Enable permanently by editing /etc/sysctl.conf
echo "net.ipv4.ip_forward=1" | sudo tee -a /etc/sysctl.conf
sudo sysctl -pFor IPv6:
sudo sysctl -w net.ipv6.conf.all.forwarding=1Implement proper error handling to catch and handle ENETUNREACH errors:
const http = require('http');
const options = {
hostname: '10.0.0.1',
port: 443,
method: 'GET'
};
const req = http.request(options, (res) => {
console.log(`Status: ${res.statusCode}`);
});
req.on('error', (err) => {
if (err.code === 'ENETUNREACH') {
console.error('Network unreachable. Check routing and network configuration.');
console.error(`Target: ${err.address}:${err.port}`);
// Implement fallback logic
// - Try alternative endpoint
// - Queue request for retry
// - Use cached data
} else {
console.error('Request failed:', err);
}
});
req.end();With axios:
const axios = require('axios');
try {
const response = await axios.get('http://10.0.0.1:443');
} catch (error) {
if (error.code === 'ENETUNREACH') {
console.error('Network unreachable:', error.message);
// Handle gracefully
}
throw error;
}Check if firewall rules are blocking traffic to the destination network:
On Linux (iptables):
# View all iptables rules
sudo iptables -L -n -v
# Check if there are DROP or REJECT rules for your destination
sudo iptables -L OUTPUT -n -v | grep 10.0.0.1On Linux (firewalld):
# Check firewall status
sudo firewall-cmd --state
# List all rules
sudo firewall-cmd --list-allOn macOS:
# Check if pf firewall is blocking
sudo pfctl -s rulesIf needed, add firewall rules to allow the traffic, but ensure you understand the security implications.
Kubernetes Network Policies: In Kubernetes environments, ENETUNREACH errors may occur due to Network Policies restricting pod-to-pod or pod-to-external communication. Review your NetworkPolicy resources and ensure egress rules permit traffic to your destination.
CNI Plugin Configuration: If using Kubernetes with CNI plugins like Flannel or Calico, verify that the CNI is selecting the correct network interface. In VirtualBox or multi-NIC environments, the CNI may default to the wrong interface (e.g., 10.0.2.x NAT interface instead of a bridge interface).
VPN and Docker Subnet Conflicts: When both VPN and Docker create overlapping subnets, routing becomes ambiguous. The system may route Docker traffic through the VPN tunnel or vice versa. Configure Docker's address pools to use non-conflicting CIDR ranges (e.g., avoid 10.0.0.0/8 if your VPN uses it).
Network Namespaces: In containerized environments, each container has its own network namespace. Use nsenter to debug routing inside a container's namespace:
# Get container PID
docker inspect -f '{{.State.Pid}}' container_name
# Enter network namespace
sudo nsenter -t <PID> -n ip routeSplit Horizon DNS: If DNS resolves to different IPs based on network location (internal vs external), you may get ENETUNREACH when your application resolves to an internal IP but doesn't have routing to reach it. Consider using environment-specific DNS or service discovery.
Errno 101: On Linux systems, ENETUNREACH corresponds to errno 101. You can check this in your system's errno.h file or using the errno command-line tool.
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