Fix: psql: error: connection to server refused (PostgreSQL)
The Error
You try to connect to PostgreSQL and get:
psql: error: connection to server at "127.0.0.1", port 5432 failed: Connection refused
Is the server running on that host and accepting TCP/IP connections?Or one of these variations:
could not connect to server: 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?psql: error: connection to server at "localhost" (::1), port 5432 failed: Connection refusedAll of these mean the same thing: your PostgreSQL client cannot reach the PostgreSQL server.
Why This Happens
PostgreSQL listens for connections on a specific address and port (default: localhost:5432). A “connection refused” error means either nothing is listening at that address, or something is actively blocking the connection.
Common causes:
- PostgreSQL isn’t running. The service was never started, crashed, or was stopped during an OS update.
- PostgreSQL is listening on a different address or port. The
listen_addressesorportsetting inpostgresql.confdoesn’t match what your client is connecting to. pg_hba.confis rejecting the connection. PostgreSQL has its own access control layer that determines which clients are allowed to connect.- A firewall is blocking port 5432.
iptables,ufw, or Windows Firewall is dropping the connection before it reaches PostgreSQL. This is similar to SSH connection timeout issues caused by firewalls. - Docker networking issues. Your app is in a container trying to reach PostgreSQL on
localhost, which resolves to the container itself, not the host or another container. - The Unix socket file is missing or in the wrong directory. Local connections on Linux/macOS use a socket file, and if it’s missing, the connection fails.
max_connectionsis exhausted. The server is running but has no connection slots left.
Fix 1: Start the PostgreSQL Service
The most common cause. PostgreSQL isn’t running.
Linux (systemd):
sudo systemctl start postgresqlCheck the status:
sudo systemctl status postgresqlIf it’s not enabled to start on boot:
sudo systemctl enable postgresqlLinux (older init systems):
sudo service postgresql startmacOS (Homebrew):
brew services start postgresql@16Replace 16 with your installed version. Check which versions are installed:
brew list | grep postgresqlIf you installed postgresql (without a version number):
brew services start postgresqlmacOS (Postgres.app):
Open the Postgres.app from your Applications folder and click Start.
Windows:
Open Services (Win+R, type services.msc), find postgresql-x64-16 (or your version), right-click, and select Start.
Or from an elevated Command Prompt:
net start postgresql-x64-16After starting, verify the connection:
psql -U postgres -h localhost -p 5432Fix 2: Check listen_addresses in postgresql.conf
PostgreSQL may be running but only listening on a specific interface. By default, it listens on localhost only — meaning it rejects connections from other machines (or from Docker containers).
Find your postgresql.conf:
# Linux (Debian/Ubuntu)
sudo cat /etc/postgresql/16/main/postgresql.conf | grep listen_addresses
# Linux (RHEL/Fedora)
sudo cat /var/lib/pgsql/16/data/postgresql.conf | grep listen_addresses
# macOS (Homebrew)
cat /opt/homebrew/var/postgresql@16/postgresql.conf | grep listen_addressesOr find it from within psql if you can connect locally:
SHOW config_file;You’ll see something like:
#listen_addresses = 'localhost'The # means it’s commented out, using the default (localhost). To accept connections from all interfaces:
listen_addresses = '*'To accept connections from specific IPs only:
listen_addresses = 'localhost,192.168.1.100'Restart PostgreSQL after changing this:
sudo systemctl restart postgresqlSecurity note: Setting listen_addresses = '*' means PostgreSQL will accept TCP connections from any network interface. This is safe if pg_hba.conf is properly configured (see Fix 3) and your firewall restricts access. Never expose PostgreSQL to the public internet without proper authentication and firewall rules.
Fix 3: Fix pg_hba.conf (Client Authentication)
Even if PostgreSQL is listening, pg_hba.conf controls which clients are allowed to connect. A misconfigured pg_hba.conf causes this error:
FATAL: no pg_hba.conf entry for host "192.168.1.50", user "myuser", database "mydb"Find the file:
# Linux (Debian/Ubuntu)
sudo nano /etc/postgresql/16/main/pg_hba.conf
# Linux (RHEL/Fedora)
sudo nano /var/lib/pgsql/16/data/pg_hba.confOr from psql:
SHOW hba_file;Add a line to allow connections from your network:
# TYPE DATABASE USER ADDRESS METHOD
host all all 127.0.0.1/32 scram-sha-256
host all all ::1/128 scram-sha-256
host all all 192.168.0.0/16 scram-sha-256For local Unix socket connections:
local all all peerReload PostgreSQL after editing (no restart required):
sudo systemctl reload postgresqlAuth methods explained:
peer— Uses the OS username to authenticate. Only works for local (Unix socket) connections.scram-sha-256— Password-based authentication (recommended).md5— Older password-based authentication. Usescram-sha-256for new setups.trust— No password required. Never use this for remote connections. Only acceptable for local development.
Fix 4: Check the Port
PostgreSQL defaults to port 5432, but another instance or service might be using it, or PostgreSQL may be configured to use a different port.
Check which port PostgreSQL is actually listening on:
# Linux / macOS
sudo ss -tlnp | grep postgresOr:
sudo netstat -tlnp | grep postgresYou’ll see output like:
tcp 0 0 127.0.0.1:5433 0.0.0.0:* LISTEN 1234/postgresIf PostgreSQL is on port 5433 (or another port), connect to it explicitly:
psql -U postgres -h localhost -p 5433To change the port permanently, edit postgresql.conf:
port = 5432If another process is occupying port 5432, find and stop it (see also Fix: Port 3000 Already in Use for general port conflict debugging):
sudo ss -tlnp | grep 5432This often happens when you have multiple PostgreSQL versions installed. Each version typically uses an incrementing port (5432, 5433, 5434).
Fix 5: Fix Docker Networking
If your application is inside a Docker container trying to connect to PostgreSQL, localhost inside the container refers to the container itself, not the host machine.
Connecting to PostgreSQL on the host from a container
Docker Desktop (macOS/Windows):
Use host.docker.internal as the hostname:
psql -U postgres -h host.docker.internal -p 5432Or in your connection string:
postgresql://postgres:password@host.docker.internal:5432/mydbLinux:
Add --network host to your docker run command, or use the host gateway:
docker run --add-host=host.docker.internal:host-gateway myappThen use host.docker.internal as the hostname in your app.
Connecting between containers (docker-compose)
Use the service name as the hostname. In your docker-compose.yml:
services:
db:
image: postgres:16
environment:
POSTGRES_PASSWORD: secret
ports:
- "5432:5432"
app:
build: .
environment:
DATABASE_URL: postgresql://postgres:secret@db:5432/mydb
depends_on:
- dbThe hostname is db (the service name), not localhost. The ports mapping is only needed if you want to access PostgreSQL from the host machine.
PostgreSQL container isn’t ready yet
If your app container starts before PostgreSQL finishes initializing, the connection fails. Add a health check and depends_on condition:
services:
db:
image: postgres:16
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_healthyFix 6: Fix the Unix Socket Path
On Linux and macOS, local connections (without -h) use a Unix socket file instead of TCP. If the socket file is missing or in the wrong location, you get:
connection to server on socket "/var/run/postgresql/.s.PGSQL.5432" failed: No such file or directoryCheck where PostgreSQL creates the socket:
sudo grep unix_socket_directories /etc/postgresql/16/main/postgresql.confThe default varies by platform:
- Debian/Ubuntu:
/var/run/postgresql - RHEL/Fedora:
/var/run/postgresqlor/tmp - macOS (Homebrew):
/tmp
Your client may be looking in a different directory. Specify the socket directory explicitly:
psql -U postgres -h /var/run/postgresqlOr if PostgreSQL uses /tmp:
psql -U postgres -h /tmpIf the socket directory doesn’t exist, create it with the correct permissions:
sudo mkdir -p /var/run/postgresql
sudo chown postgres:postgres /var/run/postgresql
sudo chmod 2775 /var/run/postgresqlThen restart PostgreSQL.
Fix 7: Fix Firewall Rules
A firewall may be silently dropping connections to port 5432.
UFW (Ubuntu):
sudo ufw status
sudo ufw allow 5432/tcpfirewalld (RHEL/Fedora/CentOS):
sudo firewall-cmd --add-port=5432/tcp --permanent
sudo firewall-cmd --reloadiptables:
sudo iptables -A INPUT -p tcp --dport 5432 -j ACCEPTWindows Firewall:
New-NetFirewallRule -DisplayName "PostgreSQL" -Direction Inbound -Protocol TCP -LocalPort 5432 -Action AllowSecurity note: Only open port 5432 to trusted networks. Exposing PostgreSQL to the public internet is a serious security risk. Use a VPN or SSH tunnel for remote access instead.
Still Not Working?
max_connections exhausted
PostgreSQL has a configurable limit on simultaneous connections (default: 100). When all slots are taken, new connections are refused with:
FATAL: sorry, too many clients alreadyCheck current connections:
SELECT count(*) FROM pg_stat_activity;Check the limit:
SHOW max_connections;To increase it, edit postgresql.conf:
max_connections = 200Restart PostgreSQL after changing this. But first, investigate why you’re hitting the limit. A connection leak in your application is a more common problem than the limit being too low. Use a connection pooler like PgBouncer for production workloads.
SSL mode mismatch
If the server requires SSL but your client isn’t using it (or vice versa):
# Force SSL
psql "postgresql://user:pass@host:5432/db?sslmode=require"
# Disable SSL (development only)
psql "postgresql://user:pass@host:5432/db?sslmode=disable"Common sslmode values:
disable— Never use SSL.require— Always use SSL, but don’t verify the server certificate.verify-full— Require SSL and verify the server certificate against a CA. Use this for production.
PostgreSQL crashed and won’t restart
Check the PostgreSQL logs:
# Debian/Ubuntu
sudo tail -50 /var/log/postgresql/postgresql-16-main.log
# RHEL/Fedora
sudo journalctl -u postgresql-16 --no-pager -n 50
# macOS (Homebrew)
tail -50 /opt/homebrew/var/log/postgresql@16.logCommon crash causes:
- Disk full. PostgreSQL won’t start if it can’t write to the data directory. Free up space and try again.
- Corrupted PID file. Remove the stale PID file and restart:
sudo rm /var/lib/postgresql/16/main/postmaster.pid
sudo systemctl start postgresqlWarning: Only remove the PID file if you’re certain PostgreSQL is not running. Check with ps aux | grep postgres first.
- Shared memory issues. On older systems, you may need to increase kernel shared memory limits. Check the logs for
could not create shared memory segmentand adjust/etc/sysctl.confaccordingly.
Wrong password or user doesn’t exist
These errors are different from “connection refused” but often get mixed up:
FATAL: password authentication failed for user "postgres"
FATAL: role "myuser" does not existReset the postgres user password:
sudo -u postgres psql -c "ALTER USER postgres WITH PASSWORD 'newpassword';"Create a missing user:
sudo -u postgres createuser --interactive myuserCloud-managed PostgreSQL (RDS, Cloud SQL, Azure)
If you’re connecting to a managed database service, “connection refused” usually means:
- Security group / firewall rules don’t allow your IP address.
- The instance is stopped or deleted.
- You’re using the wrong endpoint. Copy the hostname directly from your cloud console.
- VPC peering or private networking isn’t configured, and public access is disabled.
Check your cloud provider’s console for the exact connection details and ensure your IP is allowed in the security group or authorized networks list.
Related: If you’re troubleshooting Docker container networking issues, see Fix: Docker COPY Failed: File Not Found and Fix: Docker Permission Denied. For Kubernetes connection issues, see Fix: kubectl Connection Refused. If your application can’t read the database connection string from environment variables, see Fix: Environment Variable Is Undefined.
Related Articles
Fix: Access denied for user 'root'@'localhost' (MySQL ERROR 1045)
How to fix MySQL 'ERROR 1045 (28000): Access denied for user root@localhost (using password: YES/NO)' on Linux, macOS, Windows, and Docker. Covers password reset, auth plugin issues, skip-grant-tables recovery, MySQL 8 vs 5.7 differences, and host mismatches.
Fix: Docker Volume Permission Denied – Cannot Write to Mounted Volume
How to fix Docker permission denied errors on mounted volumes caused by UID/GID mismatch, read-only mounts, or SELinux labels.
Fix: PostgreSQL Connection Refused – Could Not Connect to Server
How to fix the PostgreSQL error 'could not connect to server: Connection refused' caused by server not running, wrong host/port, pg_hba.conf, or firewall issues.
Fix: PostgreSQL ERROR: duplicate key value violates unique constraint
How to fix 'duplicate key value violates unique constraint' in PostgreSQL by resetting sequences, using upserts, fixing bulk imports, and handling concurrent inserts.