All posts
nodejsnetworkingdebugging

ECONNREFUSED — What It Means and How to Fix It

"ECONNREFUSED" explained — why it happens, a real code example that triggers it, and the exact fix.

SR

Suhail Roushan

August 6, 2026

·
3 min read
·
0 views

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:

  1. 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.
  2. Server crashed or never started — the process exited, or you forgot to run it in a separate terminal before running your client script.
  3. Binding to a different interface — your server listens on 127.0.0.1 but you're connecting to localhost which 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.

Related posts

Written by Suhail Roushan — Full-stack developer. More posts on AI, Next.js, and building products at suhailroushan.com/blog.

Get in touch