PostgreSQL

How to Fix "Could Not Connect to Server: Connection Refused" in psql

4 min read by DebuggedIt

Quick answer

Running psql fails before you even get to a login prompt, with the connection actively refused rather than timing out or asking for a password. This means...

Running psql fails before you even get to a login prompt, with the connection actively refused rather than timing out or asking for a password. This means either PostgreSQL isn't running at all, or it's running but not listening on the address and port you're trying to reach.

The Problem

A basic connection attempt fails immediately:

$ psql -U app_user -d mydb -h localhost
psql: error: connection to server at "localhost" (127.0.0.1), port 5432 failed: Connection refused
	Is the server running on that host and accepting TCP/IP connections?

Trying a remote host produces a similar message, though the underlying cause is often different:

$ psql -U app_user -d mydb -h 203.0.113.10
psql: error: connection to server at "203.0.113.10", port 5432 failed: Connection refused
	Is the server running on that host and accepting TCP/IP connections?
Three places this can fail 1. Service not running 2. listen_addresses wrong 3. Firewall blocks 5432 Check in this order: local status, then listen config, then firewall

Why It Happens

"Connection refused" is a specific TCP-level response meaning something actively rejected the connection β€” no service was listening on that port, as opposed to a timeout, which usually means a firewall silently dropped the packets. This distinction is a useful diagnostic clue on its own. Common causes:

  • PostgreSQL isn't running at all β€” the service crashed, was never started, or failed during startup.
  • PostgreSQL is running but only listening locally β€” the default listen_addresses setting is often localhost only, which refuses any connection arriving from outside the machine itself, even if the service is healthy.
  • Wrong port β€” a non-default PostgreSQL installation, or multiple PostgreSQL versions on the same machine, listening on a port other than the standard 5432.
  • A firewall is blocking the port for remote connections β€” though this typically produces a timeout rather than an immediate refusal, some firewall configurations do actively reject rather than silently drop.

The Fix

First, confirm PostgreSQL is actually running on the target machine:

sudo systemctl status postgresql

If it's not active, start it and check the logs for why it might have failed previously:

sudo systemctl start postgresql
sudo journalctl -u postgresql --since "10 minutes ago"

If it's running but you're connecting from a different machine, check what address it's actually listening on:

sudo -u postgres psql -c "SHOW listen_addresses;"
 listen_addresses
-------------------
 localhost

A value of localhost means only local connections are accepted. For remote access, change it to listen on all interfaces (or a specific one) in postgresql.conf:

listen_addresses = '*'

This requires a full restart to take effect:

sudo systemctl restart postgresql

Changing listen_addresses alone isn't enough β€” you also need to explicitly allow the connecting host in pg_hba.conf, or PostgreSQL will still reject the connection even though it's now technically listening:

host    mydb    app_user    203.0.113.0/24    scram-sha-256

Reload PostgreSQL after editing pg_hba.conf (a reload is sufficient, no restart needed for this file):

sudo systemctl reload postgresql

Confirm the port PostgreSQL is actually bound to matches what you're connecting on:

sudo ss -tlnp | grep postgres
LISTEN 0  244  0.0.0.0:5432  0.0.0.0:*  users:(("postgres",pid=1234,fd=6))

Still Not Working?

If PostgreSQL is confirmed running and listening on the right interface but remote connections still fail, check the firewall on the server itself, since that's a completely separate layer from PostgreSQL's own configuration:

sudo ufw status
sudo ufw allow from 203.0.113.0/24 to any port 5432

If you're connecting to a managed cloud database (AWS RDS, Google Cloud SQL, etc.), check the provider's own network security configuration β€” security groups, VPC firewall rules, or authorized networks β€” since these operate entirely outside PostgreSQL's own settings and are a very common cause of this exact error for cloud-hosted databases specifically.

It's also worth distinguishing between "connection refused" and a plain timeout, since they point at different layers of the problem and knowing which one you're seeing saves significant debugging time. A refused connection, as covered above, means a TCP packet reached the target machine and something there actively rejected it β€” this points at PostgreSQL itself (not running, or not listening on that interface). A timeout, by contrast, means your connection attempt never got a response at all, which usually points at a network-level block further upstream β€” a firewall silently dropping packets, a security group rule, or a routing issue preventing the packet from ever reaching the target machine in the first place:

# Refused: PostgreSQL is reachable but rejecting
psql: error: connection to server at "203.0.113.10", port 5432 failed: Connection refused

# Timeout: something between you and the server is silently blocking traffic
psql: error: connection to server at "203.0.113.10", port 5432 failed: Connection timed out

If you're seeing a timeout rather than a refusal, focus your investigation on network-level rules (security groups, firewalls, routing) rather than PostgreSQL's own configuration, since PostgreSQL never even had the chance to accept or reject the connection in that scenario.