Skip to content

/errors/http/connect-econnrefused

Error: connect ECONNREFUSED 127.0.0.1:3000

verified onenvironmentlocal · windows 10.0.26200 arm64 · GNU bash 5.3.15 (Git Bash) · curl 8.21.0 (x86_64-w64-mingw32) libcurl/8.21.0 Schannel zlib/1.3.2updated
tool
HTTP
exit code
1
versions
Node.js 18 – 26
os
any

Error: connect ECONNREFUSED 127.0.0.1:3000 means the operating system rejected the TCP connection: no process is listening on that address and port. It happens before any HTTP request is sent, so it is never an HTTP status code. Start the server, check that host and port match, and remember that localhost can resolve to the IPv6 address ::1.

Reproduce it

Nothing listens on port 4199 here:

bash
cat > client.js <<'EOF'
require("http").get("http://127.0.0.1:4199/").on("error", (e) => console.log(`${e.name}: ${e.message} (code ${e.code})`));
EOF
node client.js
curl -sS http://127.0.0.1:4199/ 2>&1 | sed -E 's/after [0-9]+ ms/after N ms/'

Output

Error: connect ECONNREFUSED 127.0.0.1:4199 (code ECONNREFUSED)
curl: (7) Failed to connect to 127.0.0.1:4199 after N ms: Could not connect to server

curl reports the same condition as exit code 7, Failed to connect.

IPv4 vs IPv6: localhost and ::1

A server bound to 127.0.0.1 does not accept connections on ::1:

bash
cat > server.js <<'EOF'
require("http").createServer((req, res) => res.end("ok\n")).listen(4198, "127.0.0.1");
setTimeout(() => process.exit(0), 3000);
EOF
cat > client.js <<'EOF'
const host = process.argv[2];
require("http").get({ host, port: 4198, path: "/", agent: false }, (res) => { res.resume(); console.log(host, "->", res.statusCode); })
  .on("error", (e) => console.log(host, "->", e.message));
EOF
node server.js &
sleep 1
node client.js 127.0.0.1
node client.js ::1

Output

127.0.0.1 -> 200
::1 -> connect ECONNREFUSED ::1:4198

Since Node.js 17, localhost is resolved in the order the operating system returns, often ::1 first. Node.js 20 and later try both families (autoSelectFamily), so http://localhost:4198 usually works; older versions failed with connect ECONNREFUSED ::1:4198. Listening on :: (all IPv6, and IPv4 on most systems) or using 127.0.0.1 on both sides avoids the mismatch.

Checklist

CheckCommand
Is anything listening on the port? (Linux)ss -ltnp | grep 3000
Same, macOSlsof -iTCP:3000 -sTCP:LISTEN
Same, Windowsnetstat -ano | findstr :3000
Does the port answer?curl -v http://127.0.0.1:3000/
Inside Docker Composeuse the service name, not localhost

Sources