Fix 'Error: connect ECONNREFUSED 127.0.0.1:5432' in Node.js

beginner๐Ÿ’š Node.js2026-05-09| Node.js (v14+), PostgreSQL / MySQL / Redis / any TCP server, Linux / macOS / Windows

Error Message

Error: connect ECONNREFUSED 127.0.0.1:5432
#nodejs#network#database

The Error

You run your Node.js app and it crashes โ€” either immediately or mid-request โ€” with something like:

Error: connect ECONNREFUSED 127.0.0.1:5432
    at TCPConnectWrap.afterConnect [as oncomplete] (node:net:1187:16) {
  errno: -111,
  code: 'ECONNREFUSED',
  syscall: 'connect',
  address: '127.0.0.1',
  port: 5432
}

The port number shifts based on what you're connecting to: 5432 for PostgreSQL, 3306 for MySQL, 6379 for Redis, 27017 for MongoDB, or whatever custom port your service uses. The root cause is always the same: Node.js tried to open a TCP connection to that address and port, and nothing answered.

Root Causes

  • The database or service is simply not running.
  • The service is running but on a different port than your config expects.
  • The service is bound to a different interface (e.g. ::1 IPv6 instead of 127.0.0.1 IPv4).
  • A firewall or Docker network is blocking the connection.
  • Your app started before the database finished booting (race condition in Docker Compose).
  • Wrong host/port in your connection string or .env file.

Step 1 โ€” Check Whether the Service Is Running

This fixes the problem 90% of the time.

Linux / macOS

# Check if anything is listening on the target port
sudo ss -tlnp | grep 5432
# or
sudo lsof -i :5432

No output means the service is down. Start it:

# PostgreSQL
sudo systemctl start postgresql

# MySQL / MariaDB
sudo systemctl start mysql

# Redis
sudo systemctl start redis

Windows

netstat -ano | findstr :5432

Nothing listed? Open Services (services.msc) and start the relevant service, or use the application's own start command.

Step 2 โ€” Verify Your Connection Config

Service is up? Now make sure your app is actually pointing where you think it is. A stale .env or a one-character typo is enough to break the connection.

# .env example
DB_HOST=127.0.0.1
DB_PORT=5432
DB_USER=myuser
DB_PASSWORD=secret
DB_NAME=mydb

Cross-reference with what's actually in your connection code:

// pg (node-postgres)
const { Pool } = require('pg');
const pool = new Pool({
  host: process.env.DB_HOST,
  port: Number(process.env.DB_PORT),
  user: process.env.DB_USER,
  password: process.env.DB_PASSWORD,
  database: process.env.DB_NAME,
});

Log the resolved values before connecting โ€” don't guess:

console.log('Connecting to', process.env.DB_HOST, ':', process.env.DB_PORT);

Step 3 โ€” Check the Bind Address (IPv4 vs IPv6)

Some installations bind only to ::1 (IPv6 loopback), while your app connects to 127.0.0.1 (IPv4). They look the same. They are not โ€” separate sockets entirely.

sudo ss -tlnp | grep 5432
# If you see  *:5432  or  :::5432 โ€” it's IPv6 only

Quick fix: switch your host to localhost and let Node.js resolve it, or use ::1 directly:

DB_HOST=localhost   # Node resolves to whichever interface is available

Alternatively, tell PostgreSQL to bind both interfaces by editing postgresql.conf:

listen_addresses = 'localhost'   # listens on both 127.0.0.1 and ::1

Step 4 โ€” Docker Compose Race Condition

Running Node.js and a database together in Docker Compose? Your app container almost certainly starts before the DB is ready. depends_on doesn't help here โ€” it only waits for the container to start, not for PostgreSQL inside it to finish booting.

The fix is a health check plus condition: service_healthy:

services:
  db:
    image: postgres:15
    environment:
      POSTGRES_PASSWORD: secret
    healthcheck:
      test: ["CMD-SHELL", "pg_isready -U postgres"]
      interval: 5s
      timeout: 5s
      retries: 5

  app:
    build: .
    depends_on:
      db:
        condition: service_healthy
    environment:
      DB_HOST: db
      DB_PORT: 5432

Note: in Docker Compose, use the service name (db) as the host, not 127.0.0.1.

Step 5 โ€” Add Retry Logic in Your App

A single ECONNREFUSED shouldn't kill your entire process. Wire in a retry loop โ€” it takes about 15 lines and saves a lot of on-call headaches:

const { Pool } = require('pg');

const pool = new Pool({ connectionString: process.env.DATABASE_URL });

async function connectWithRetry(retries = 5, delay = 2000) {
  for (let i = 0; i  setTimeout(r, delay));
    }
  }
  throw new Error('Could not connect to database after multiple retries');
}

connectWithRetry();

Verification

Before restarting your full app, confirm the connection works at the TCP level:

# Test TCP connectivity directly
nc -zv 127.0.0.1 5432
# Expected: Connection to 127.0.0.1 5432 port [tcp/postgresql] succeeded!

# PostgreSQL: test login
psql -h 127.0.0.1 -p 5432 -U myuser -d mydb -c 'SELECT 1;'

# MySQL:
mysql -h 127.0.0.1 -P 3306 -u myuser -p mydb -e 'SELECT 1;'

# Redis:
redis-cli -h 127.0.0.1 -p 6379 ping
# Expected: PONG

Quick Reference by Port

  • 5432 โ€” PostgreSQL: sudo systemctl start postgresql
  • 3306 โ€” MySQL/MariaDB: sudo systemctl start mysql
  • 6379 โ€” Redis: sudo systemctl start redis
  • 27017 โ€” MongoDB: sudo systemctl start mongod

Tips

Dealing with containers or custom network setups? The Subnet Calculator on ToolCraft lets you check CIDR ranges and confirm that your container IPs fall within the expected network. Runs entirely in the browser โ€” nothing uploaded.

Related Error Notes