Error: connect ECONNREFUSED 127.0.0.1:PORT is about as direct as network errors get: your application tried to connect to something on your own machine at a specific port, and nothing was listening there — no DNS ambiguity, no remote network involved, just a local port with no service behind it.
This error means a TCP connection attempt to 127.0.0.1 (localhost) on the specified port was actively refused by the operating system, which happens specifically when no process is currently listening on that port — distinct from a timeout (where something might be there but not responding) or a DNS failure (where the hostname itself couldn't resolve).
Why This Error Happens
When nothing is bound to a port, the OS immediately sends a TCP RST (reset) in response to a connection attempt, which Node.js surfaces as ECONNREFUSED. Locally, this near-always means the service you're trying to connect to (a database, another local server, a development API) either isn't running, is running on a different port than expected, crashed after starting, or hasn't finished starting up yet when your application tried to connect.
Reproducing and Diagnosing the Error
A common local development scenario — application starting before its database is ready:
const client = new MongoClient("mongodb://127.0.0.1:27017");
await client.connect();
// Error: connect ECONNREFUSED 127.0.0.1:27017
// if MongoDB isn't actually running, or hasn't started listening yet
Diagnosing which service (if any) is actually listening on the port:
lsof -i :27017
# or: netstat -an | grep 27017
# Empty output confirms nothing is listening — the direct cause of ECONNREFUSED
Core Concepts Behind This Error
The service simply isn't running is the most common cause by far in local development — a database, cache, or dependent local server that was expected to already be started (perhaps via a separate terminal, a docker-compose up, or a background process) but wasn't, or crashed after an initial successful start.
Startup ordering matters in multi-service local development — if your application starts and attempts a connection before a dependency (a database, for instance) has finished its own startup sequence and begun listening, you'll get ECONNREFUSED even though the dependency is in the process of starting correctly, just not quite ready yet.
Port mismatches between what your application expects and what the service is actually configured to use are a common configuration-drift cause — an environment variable pointing at the wrong port, or a service's default port differing from what your application's connection string assumes.
Docker networking adds another layer of port-related confusion — a service running inside a container isn't reachable at 127.0.0.1 from your host machine (or another container) unless the container's port is explicitly published/mapped, and getting this mapping wrong produces the exact same ECONNREFUSED symptom.
Fixing "ECONNREFUSED 127.0.0.1"
Fix 1: Verify the service is actually running and listening on the expected port, the first and most common fix:
lsof -i :27017
# If empty, start the service:
brew services start mongodb-community
# or: docker-compose up -d mongodb
Fix 2: Add startup ordering/retry logic for applications with local dependencies that might not be ready immediately, rather than assuming instant availability:
async function connectWithRetry(url: string, attempts = 5) {
for (let i = 0; i < attempts; i++) {
try {
const client = new MongoClient(url);
await client.connect();
return client;
} catch (err: any) {
if (err.code !== "ECONNREFUSED" || i === attempts - 1) throw err;
await new Promise((r) => setTimeout(r, 1000 * (i + 1)));
}
}
throw new Error("unreachable");
}
Fix 3: Verify port configuration matches between your application's connection string and the service's actual configuration, particularly after changing a service's default port or when using environment variables:
echo $DATABASE_PORT # verify this matches what the actual service is configured to use
Fix 4: For Docker-based services, verify the container's port is properly published to the host:
# docker-compose.yml
services:
mongodb:
image: mongo
ports:
- "27017:27017" # host:container — required for host-machine access via 127.0.0.1
Why Does This Error Sometimes Happen Only Intermittently in CI, Not Locally?
Because CI environments frequently start multiple services (your application and its dependencies) concurrently rather than sequentially, and a dependency that starts fast enough locally (where you might manually start it first, or it's been running for a while) can genuinely not be ready yet when your application's connection attempt fires in a fresh CI run — this is specifically a startup-ordering race condition, and the fix is retry logic or an explicit "wait for service ready" step in your CI configuration, not a code bug in the connection logic itself.
Preventing This Error in Production
Add connection retry logic with backoff for any service startup sequence involving local or tightly-coupled dependencies, since startup ordering isn't always guaranteed even with process orchestration tools. In CI and containerized environments specifically, use explicit health checks or "wait for it" scripts to ensure dependencies are actually ready before your application attempts to connect, rather than relying on incidental timing that happens to work locally.
If you hit this error, check first whether the target service is actually running (lsof -i :PORT) — that single check resolves the large majority of local ECONNREFUSED cases faster than debugging application code.