ECONNREFUSED is Node.js's error code for when a TCP connection is actively rejected by the target machine — the port is closed or nothing is listening there.
What "ECONNREFUSED" Means
The server you're trying to reach is up, but the specific port you're connecting to has no process listening on it. The OS received your SYN packet and responded with RST (reset) because nothing accepted the connection. Unlike a timeout (which means the host is unreachable or firewalled), ECONNREFUSED is a definitive "no one is home" answer.
Why It Happens
The three most common real causes:
- Wrong port number — you're connecting to port 3000 but the server started on 3001. Node.js doesn't care about the port you intended; it connects to whatever you passed.
- Server crashed or never started — the process exited, or you forgot to run it in a separate terminal before running your client script.
- Binding to a different interface — your server listens on
127.0.0.1but you're connecting tolocalhostwhich resolves to::1(IPv6) in modern Node.js, and the server isn't bound to IPv6.
Example Code That Triggers It
Here's a minimal Node.js client that will throw ECONNREFUSED if nothing is listening on port 4000:
import net from 'node:net';
const socket = net.createConnection({ port: 4000, host: '127.0.0.1' });
socket.on('connect', () => {
console.log('Connected!');
socket.end();
});
socket.on('error', (err) => {
console.error(`Failed: ${err.code}`); // Output: Failed: ECONNREFUSED
});
Run this with no server on port 4000 and you'll get the error within milliseconds.
How to Fix It
The corrected code — start a server first, then connect:
import net from 'node:net';
// Server
const server = net.createServer((socket) => {
socket.write('hello');
socket.end();
});
server.listen(4000, '127.0.0.1', () => {
console.log('Server listening on 127.0.0.1:4000');
});
// Client (run after server is up)
const socket = net.createConnection({ port: 4000, host: '127.0.0.1' });
socket.on('connect', () => {
console.log('Connected!');
socket.end();
});
socket.on('error', (err) => {
console.error(`Failed: ${err.code}`);
});
The fix works because the server is bound to the exact same interface (127.0.0.1) and port (4000) the client connects to. If you bind the server to 0.0.0.0 or omit the host, it accepts connections on all interfaces — but then you must connect via the IP the OS exposes, not assume localhost.
Common Mistakes That Cause This
Mistake 1: Using localhost when the server binds to 127.0.0.1. In Node.js 17+, localhost can resolve to ::1 (IPv6). If your server binds only to IPv4, the connection is refused. Always use 127.0.0.1 explicitly in local dev.
Mistake 2: Forgetting the server runs in a separate process. Beginners write a single file that both starts a server and immediately connects. The connection attempt races ahead of the listen() callback. Use server.listen() with a callback, then connect from a separate script or after the callback fires.
When Should You Worry About This?
If you're in production and suddenly see ECONNREFUSED, it's a real outage — your process crashed or your load balancer is routing to a dead instance. Check systemctl status or your orchestrator's health checks immediately. In development, it's almost always a config mismatch, not a systemic issue. If it happens intermittently in production, check for connection pool exhaustion or a service that's restarting in a loop.
First thing to check next time: run lsof -i :<port> (Linux/macOS) or netstat -ano | findstr :<port> (Windows) to see if anything is actually listening on the port you're targeting.