Node.js — ECONNREFUSED when connecting to a service
Diagnose ECONNREFUSED by checking whether anything listens on the target host and port and whether the address resolves as expected.
Symptoms
- Error: connect ECONNREFUSED 127.0.0.1:5432
- The client starts but every request fails immediately
- It works from your machine but fails inside Docker or Kubernetes
- The service was reachable earlier and now refuses connections
Possible causes
- No process is listening on the target port
- The service is bound to a different interface or address than the client targets
- Inside a container, localhost refers to the container rather than the host
- The service crashed or has not finished starting
Diagnosis steps
Check whether the port is listening
ss -ltnp | grep :5432Interpretation
No listener means the service is down or bound elsewhere. A listener on 127.0.0.1 only will refuse connections addressed to another interface.
Test from the same network context
node -e "require('net').connect(5432,'db').on('error',e=>console.log(e.code))"Interpretation
Running the check from inside the container or pod distinguishes a network path problem from an application bug.
Verify name resolution
node -e "require('dns').lookup('db',(e,a)=>console.log(e||a))"Interpretation
If the hostname resolves to an unexpected address, the client is dialing the wrong place.
Root cause
The TCP connection was actively refused because nothing accepted it at the resolved address and port, which means the service is not listening there or is unreachable from the client network.
Fix
Start or restart the service, bind it to the interface the client uses, fix the hostname so it resolves to the right address, and adjust container networking so services can reach each other.
Verify the fix
Retry the connection and confirm it succeeds, then confirm the expected request works end to end rather than only the socket opening.
Symptom walkthrough
A connection attempt fails fast with ECONNREFUSED, which is different from a timeout: the peer responded with a refusal, so the packet reached a host that had nothing listening on that port. It is very common to see this work on a laptop but fail inside a container, where localhost points at the container itself rather than the host machine running the database.
Fix in practice
Confirm a listener exists on the resolved address and port, then correct the mismatch. Inside containers, use the service name on the shared network instead of localhost. If the service simply is not up yet, add a readiness check or retry with backoff rather than assuming a code defect.
Verification
Reconnect and confirm the handshake succeeds, then exercise a real request to prove the service is functional, not merely accepting sockets.
Diagnostic commands
Check the behavior with commands like these:
ss -ltnp | grep :5432
node -e "require('net').connect(5432,'db').on('error',e=>console.log(e.code))"
node -e "require('dns').lookup('db',(e,a)=>console.log(e||a))"