All posts
nodejsnetworking

Fixing "Error: connect ECONNREFUSED 127.0.0.1"

Why Node.js throws ECONNREFUSED for local connections, common local development causes, and how to fix each one.

SR

Suhail Roushan

August 6, 2026

·
5 min read
·
0 views

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.

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