Fix PostgreSQL Connection Refused Errors
A practical quick fix for PostgreSQL connection refused errors, including how to separate network, listener, port, firewall, and connection string causes.
A PostgreSQL connection refused error means the client reached an address, but nothing accepted the TCP connection on the requested port. That is different from a bad password, a missing database, or a pg_hba.conf rejection. Authentication has not started yet; the client is still trying to find a PostgreSQL listener.
The useful response is to narrow the failure before changing credentials or database permissions. In practice, the cause is usually one of five things: PostgreSQL is down, it is listening on a different interface, the client is using the wrong host or port, a firewall or network rule is blocking the path, or a local Unix socket path is being mistaken for a TCP host.
First confirm what kind of connection failed
Start with the exact connection target. A connection string such as host=localhost port=5432 dbname=app user=app tests a different path than host=db.example.com port=5432 dbname=app user=app, and both are different from a socket connection that omits the host. PostgreSQL's libpq client library treats connection parameters as explicit instructions: host, hostaddr, port, dbname, user, TLS settings, and other parameters all influence where the client tries to connect.
If the error says connection refused, the address normally resolved and the remote side actively rejected or had no listener on that port. If the error says could not translate host name, fix DNS first. If it says timeout expired, suspect routing, firewall rules, private networking, or a dropped packet path. Keeping those cases separate prevents long debugging sessions in the wrong layer.
| Symptom | Likely layer | What to check first |
|---|---|---|
connection refused on localhost | PostgreSQL listener or local service state | Is the server running, and is it listening on the requested port? |
connection refused only from another machine | Listen address or network boundary | Check listen_addresses, private network rules, and the target hostname |
| Timeout instead of refused | Firewall, routing, or security group | Confirm the port is allowed between the client and database |
| Works with IP but not hostname | DNS or wrong endpoint | Verify the hostname, environment variable, and connection string source |
| Works locally but not in production | Deployment configuration | Compare host, port, SSL mode, and secret values across environments |
Check server readiness before changing credentials
Use a readiness probe before editing users or grants. The PostgreSQL tool pg_isready reports whether a server is accepting connections at a host and port. It does not prove that your username or database name is correct, but it is ideal for separating listener problems from authentication problems. Test the same host and port your application uses, not just the default local socket.
On a self-hosted system, also inspect the service state and the configured port. PostgreSQL defaults to port 5432, but multi-cluster installs, containers, and local development stacks often move it. If the server recently restarted, read the PostgreSQL log around startup. A bind failure, invalid config file, missing data directory, or occupied port can leave clients seeing only a refused connection.
Managed PostgreSQL changes the checklist slightly. You usually cannot inspect the database host's process table, so verify the provider dashboard status, the exact endpoint, the plan's networking mode, and whether the app is running inside the allowed network. If ArmorDB is hosting the database, start with the connection details in the dashboard and compare them against the secret your app actually received at deploy time.
Verify listen addresses and network reachability
PostgreSQL listens only where it is configured to listen. The listen_addresses setting controls the TCP/IP addresses the server binds to, while port controls the port. A server that listens only on localhost can work perfectly for local tools while refusing connections from an application container, another VM, or a teammate's laptop. Changing this setting on self-hosted PostgreSQL normally requires a restart, so avoid guessing; confirm the current value first.
Do not confuse listener configuration with host-based authentication. The pg_hba.conf file decides which hosts, users, databases, and authentication methods are allowed after the client reaches the server. If the server is not listening on the network path, pg_hba.conf is never consulted. Once you stop getting refused connections, you may still need to fix a no pg_hba.conf entry or password error, but that is the next stage rather than the first fix.
Containers add one more trap. Inside a container, localhost usually means the container itself, not the host machine and not another service. In Docker Compose, the database host is often the service name. In Kubernetes, it is usually a Service DNS name. A connection string copied from a laptop can therefore be correct for local psql and wrong for the deployed application.
A safe recovery sequence
First, preserve the failing error message and connection target so you can compare before and after. Next, test the endpoint with pg_isready or a simple client from the same environment as the failing app. If the database is self-hosted, confirm PostgreSQL is running and listening on the expected port. If it is managed, confirm the instance status and that the application uses the current endpoint, not a deleted branch, old host, or local default.
Then check the network boundary closest to the client. For cloud deployments, that may be a security group, private network attachment, egress rule, or provider allowlist. For local development, it may be a stopped container, an unpublished port, or a connection string that points to localhost when the database lives in another container. Only after the connection reaches PostgreSQL should you spend time on users, passwords, database names, grants, and schema privileges.
Prevent it from coming back
Store database connection strings in one deployment secret per environment and keep examples clearly marked as examples. During deploys, add a readiness check that tests the same host and port before the application begins taking traffic. For production systems, keep a short runbook that names the database endpoint, the expected port, whether traffic is private or public, and where network allowlists are managed.
If the application opens many short-lived connections after the endpoint is fixed, consider a pooler. PgBouncer will not fix a refused connection to the wrong host, but it can reduce connection churn once the network path is healthy. ArmorDB includes PgBouncer for this reason; the PgBouncer documentation is the right next read when refused connections turn into saturation or connection-limit errors.
Takeaway
Treat connection refused as a listener and network problem until proven otherwise. Confirm the exact host and port, check readiness from the same runtime that failed, verify that PostgreSQL is listening where the client is connecting, and then inspect firewalls or private networking. Authentication and grants matter later, but they cannot explain a refusal that happens before PostgreSQL accepts the connection.
Sources and further reading
Topic
Short-Form & Quick Fixes
Updated
Jul 24, 2026
Read time
5 min read
ArmorDB Engineering writes about PostgreSQL operations, security, and infrastructure decisions for teams building production apps on ArmorDB.
Read next
Tech-News & Trends · 6 min read
PostgreSQL 18 NOT NULL Constraints: What Changed for Safer Schema Changes
PostgreSQL 18 makes NOT NULL constraints more explicit and easier to manage, with named constraints, catalog storage, NOT VALID support, and inheritance controls.
Read articleData-Specs / Vergleiche · 7 min read
PostgreSQL Backup Methods Compared: Dumps, Base Backups, WAL, and Snapshots
Compare PostgreSQL backup methods by restore goal, recovery window, operational cost, and managed database fit before choosing a production policy.
Read article