| title | PostgreSQL Connection Refused | |||||
|---|---|---|---|---|---|---|
| slug | postgresql-connection-refused | |||||
| technologies |
|
|||||
| severity | high | |||||
| tags |
|
|||||
| related |
|
|||||
| last_reviewed | 2026-06-27 |
psql: error: connection to server at "db.internal" (10.0.3.21), port 5432 failed: Connection refused
Is the server running on that host and accepting TCP/IP connections?
psql: error: connection to server on socket "/var/run/postgresql/.s.PGSQL.5432" failed: No such file or directory
Is the server running locally and accepting connections on that socket?
Connection refused is a TCP/transport-level failure: the client reached the
target host, but nothing was listening on the requested port, so the kernel
returned ECONNREFUSED. This happens before any PostgreSQL authentication or
pg_hba.conf evaluation β the server process either is not running, is not bound
to the address/port the client used, or a firewall is rejecting the packet. The
Unix-socket variant (No such file or directory) means the local server is not
running or its socket lives in a different directory than the client expects.
- postgresql (postmaster / listener, libpq client)
high β no client can connect over the affected path. For a single-instance database this is a full outage; for an HA setup it may be a failover trigger.
- The PostgreSQL service is stopped or crashed (most common).
listen_addressesislocalhost(or empty), so the server never binds the network interface the client is using.- The client used the wrong port, or PostgreSQL is running on a non-default port.
- A host firewall (firewalld/iptables/ufw) or a cloud security group is dropping or rejecting traffic to port 5432.
- Unix-socket directory mismatch: client expects
/tmpbut the server writes its socket to/var/run/postgresql(or vice versa).
libpq attempts a TCP connect() (or a Unix-domain connect() for local socket
hosts). If the destination port has no listening socket, the kernel immediately
replies with a TCP RST and libpq surfaces Connection refused. This is distinct
from a timeout (Connection timed out), which indicates packets are being
silently dropped β typically a firewall in DROP mode or an unreachable host.
Because the rejection happens at the transport layer, PostgreSQL never logs the
attempt: the client error is the only evidence. The job, then, is to prove
whether the server is up, what address/port it is bound to, and whether anything
in the network path is blocking the SYN.
# Fastest health probe β does the server answer on host:port?
pg_isready -h db.internal -p 5432
# Is the service actually running?
systemctl status postgresql
# What is the server bound to? Look for 0.0.0.0:5432 or 127.0.0.1:5432
ss -ltnp | grep 5432
# Confirm the configured listen address and port from inside (if reachable locally)
sudo -u postgres psql -c "SHOW listen_addresses;" -c "SHOW port;"
# Recent server-side startup/crash messages
journalctl -u postgresql --since "30 min ago" --no-pager# pg_isready when the listener is down:
db.internal:5432 - no response
# ss showing the server bound ONLY to loopback (remote clients get refused):
LISTEN 0 244 127.0.0.1:5432 0.0.0.0:* users:(("postgres",pid=812,fd=6))
# Healthy: bound to all interfaces
LISTEN 0 244 0.0.0.0:5432 0.0.0.0:* users:(("postgres",pid=812,fd=6))
-
If the service is down, start it and check why it stopped:
sudo systemctl start postgresql sudo journalctl -u postgresql --since "1 hour ago" --no-pager -
To accept remote connections, set
listen_addressesinpostgresql.confand reload (a restart is required forlisten_addresseschanges):listen_addresses = '*' # or a comma-separated list of specific IPs port = 5432
sudo systemctl restart postgresql
-
Open the firewall to the trusted client range (example, firewalld):
sudo firewall-cmd --add-rich-rule='rule family=ipv4 source address=10.0.0.0/16 port port=5432 protocol=tcp accept' --permanent sudo firewall-cmd --reload -
For the socket variant, point the client at the correct directory with the
hostparameter, e.g.psql -h /var/run/postgresql.
pg_isready -h db.internal -p 5432
# Expect: db.internal:5432 - accepting connections
psql -h db.internal -p 5432 -U app -d appdb -c "SELECT 1;"- Monitor the listener with
pg_isreadyfrom outside the host, not just locally. - Manage
listen_addresses,port, and firewall rules in configuration code so drift does not silently break connectivity. - Add a startup health check / alert on the
postgresqlsystemd unit so crashes page someone instead of being discovered by clients.
postgresql Β· connectivity Β· networking Β· startup Β· production