Blog
4 min read

ECONNREFUSED 127.0.0.1:5432: Why Your App Can't Reach the Database

"connect ECONNREFUSED 127.0.0.1:5432" means nothing was listening where your app tried to connect. The causes: database not running, wrong host inside Docker, wrong port, listening on the wrong address, or a firewall. How to find which, plus the related timeout and authentication errors.

Error: connect ECONNREFUSED 127.0.0.1:5432
psql: error: connection to server at "localhost" (::1), port 5432 failed: Connection refused

Connection refused means your app knocked on a door and nobody was there. It reached the computer, but no program was listening on that port. For Postgres the port is usually 5432; for MySQL 3306; for Redis 6379; for MongoDB 27017. The same reasoning applies to all of them.

The good news: it's not a password problem and not a code bug. It's an address problem.

Read the error carefully

127.0.0.1:5432 tells you two things: where it tried (127.0.0.1, which is "this same machine") and which port (5432). (What is localhost?, ports explained) Each cause below is about one of those being wrong.

Cause 1: The database isn't running

The most common one, especially after a restart.

# Postgres installed directly
sudo systemctl status postgresql        # Linux
brew services list                      # macOS with Homebrew

# Postgres in Docker
docker ps                               # is the container up?
docker compose up -d db

If it's stopped or crashing, start it and check its logs for why.

Cause 2: Your app is in a container, and "localhost" means the container

This catches almost everyone using Docker. Inside a container, localhost refers to that container, not your computer and not the database container.

With Docker Compose, use the service name as the host:

services:
  app:
    environment:
      DATABASE_URL: postgres://postgres:secret@db:5432/app   # "db", not localhost
  db:
    image: postgres:18

If the app runs on your computer and the database in Docker, localhost works only if the port is published (ports: ["127.0.0.1:5432:5432"]). (Docker Compose for local development)

Cause 3: Wrong port

Another Postgres (or a second version) might be on 5432, pushing yours to 5433. Or the connection string has a typo. Check what's actually listening:

sudo ss -ltnp | grep 543      # Linux
lsof -iTCP -sTCP:LISTEN | grep 543   # macOS

(Postgres connection strings explained)

Cause 4: The database only listens on another address

Postgres listens on localhost by default. If your app connects from another machine or container using the server's IP, it's refused. On a server you control, listen_addresses in postgresql.conf and rules in pg_hba.conf control this — but think twice: don't expose your database to the internet. Use a private network or an SSH tunnel. (SSH port forwarding)

Cause 5: IPv6 vs IPv4

Notice ::1 in the second error above. localhost can resolve to the IPv6 address ::1, while your database listens only on IPv4 127.0.0.1. Use 127.0.0.1 explicitly in the connection string, and the problem disappears.

Cause 6: It's starting up

In Docker Compose, the app container often starts before Postgres is ready to accept connections. Add a health check and depends_on: condition: service_healthy, or retry the connection at startup.

Error Means
ECONNREFUSED Reached the machine; nothing listening on that port
ETIMEDOUT / timeout Couldn't reach the machine at all — firewall, wrong IP, network
ENOTFOUND / getaddrinfo The hostname doesn't resolve — typo, or a Docker service name used outside Docker
password authentication failed Connected fine; wrong username or password
database "x" does not exist Connected and logged in; wrong database name
no pg_hba.conf entry Server refused this user/address combination
too many connections Connection limit reached (connection pooling)
SSL required / self-signed certificate Hosted databases need sslmode set correctly

Getting from "refused" to "password failed" is progress — it means the address is now right.

In production

If it works locally but production shows ECONNREFUSED, the production DATABASE_URL is probably missing or still says localhost. (Why your app works locally but not in production)

The summary

  • Connection refused = nothing listening at that host and port.
  • Check the database is running first.
  • In Docker, use the service name, not localhost.
  • Check the port, and try 127.0.0.1 instead of localhost.
  • Timeouts, unknown hosts and auth failures are different problems.

EasySpawn servers come with PostgreSQL running alongside your app, with the connection string already set — no ports or Docker networking to get wrong. See how it works or join the waitlist.

Related: Postgres Connection Strings Explained · What Is Localhost? · Docker Compose for Local Development · How to View Your Postgres Database

Keep reading