Connection exceptions in PostgreSQL occur when the client fails to establish or maintain a TCP/IP connection to the database server. This can happen due to the server not running, network issues, firewall blocking, or incorrect connection parameters.
Fixes 08000
sudo systemctl status postgresql
# or for specific versions like postgresql-15
sudo systemctl status postgresql-15sudo systemctl status postgresql# or for specific versions like postgresql-15sudo systemctl status postgresql-15Connection exception
A "Connection exception" in PostgreSQL is represented by SQLSTATE class 08 errors and indicates that the client cannot connect to the PostgreSQL server. This is distinct from authentication errors (SQLSTATE 28) - the connection itself is failing before credentials are even evaluated. Connection exceptions can occur at different stages: - **Connection initiation**: The TCP connection attempt is refused, times out, or encounters network errors - **Connection drop**: An established connection suddenly closes during communication - **DNS resolution**: Hostname cannot be resolved to an IP address - **Port issues**: The specified port is not listening or is blocked The most common SQLSTATE 08 codes you'll encounter are: - **08001**: sqlclient_unable_to_establish_sqlconnection - Cannot establish connection - **08003**: connection_does_not_exist - The connection was closed or never established - **08006**: connection_failure - Connection lost during command execution
First, confirm the PostgreSQL daemon is actually running on the target system.
On Linux:
sudo systemctl status postgresql
# or for specific versions like postgresql-15
sudo systemctl status postgresql-15On macOS with Homebrew:
brew services list | grep postgresOn Windows (PowerShell as Administrator):
Get-Service postgresql*On Docker:
docker ps | grep postgresIf PostgreSQL is not running, start it:
# Linux
sudo systemctl start postgresql
# macOS
brew services start postgresql
# Windows - Open Services and start PostgreSQL service
# Docker
docker run --name postgres -p 5432:5432 -e POSTGRES_PASSWORD=password postgresPostgreSQL defaults to port 5432, but may be configured differently. Verify it's listening:
On Linux/macOS:
# Check if port 5432 is listening
netstat -tlnp | grep postgres
# or
ss -tlnp | grep postgres
# or
lsof -i :5432On Windows (PowerShell as Administrator):
netstat -ano | findstr :5432Docker:
docker port <container_name>If no process is listening on 5432, either:
1. PostgreSQL is not running (refer to Step 1)
2. PostgreSQL is listening on a different port
To find the actual port, check the PostgreSQL configuration:
# Linux - check postgresql.conf
grep "^port = " /etc/postgresql/*/main/postgresql.conf
# Docker - check startup logs
docker logs <container_name> | grep "listening on"Ensure your connection string uses the correct hostname and that it resolves properly.
Check DNS resolution:
# Test hostname resolution
nslookup postgres.example.com
dig postgres.example.com
getent hosts postgres.example.com
# or use ping (works on most systems)
ping postgres.example.com
ping localhost
ping 127.0.0.1Common connection string formats:
# Standard format
postgresql://username:password@hostname:5432/database_name
# Examples:
postgresql://postgres:password@localhost:5432/mydb
postgresql://postgres:[email protected]:5432/mydb
postgresql://postgres:[email protected]:5432/mydbTest local vs remote:
- Use localhost or 127.0.0.1 for connections from the same machine
- Use the actual hostname or IP for remote connections
- Avoid using localhost for remote connections - it won't resolve correctly
By default, PostgreSQL only listens on localhost. For remote connections, configure it to listen on all interfaces.
Edit postgresql.conf:
# Find postgresql.conf location
sudo -u postgres psql -c "SHOW config_file"
# Edit the file (example for Linux)
sudo nano /etc/postgresql/15/main/postgresql.confFind and modify the listen_addresses setting:
# Default (localhost only):
listen_addresses = 'localhost'
# Change to listen on all interfaces:
listen_addresses = '*'
# Or listen on specific IP addresses:
listen_addresses = 'localhost,192.168.1.100'Restart PostgreSQL for changes to take effect:
sudo systemctl restart postgresql
# or on macOS
brew services restart postgresqlVerify the change:
ss -tlnp | grep postgres
# Should show something like:
# LISTEN 0 244 0.0.0.0:5432 0.0.0.0:* ...The pg_hba.conf file controls which clients can connect. Incorrect rules will cause connection exceptions.
Locate pg_hba.conf:
# Query the location
sudo -u postgres psql -c "SHOW hba_file"
# Usually at:
# Linux: /etc/postgresql/*/main/pg_hba.conf
# macOS: /usr/local/var/postgres/pg_hba.conf
# Windows: C:\Program Files\PostgreSQL\15\data\pg_hba.confExample pg_hba.conf rules:
# TYPE DATABASE USER ADDRESS METHOD
local all all trust
host all all 127.0.0.1/32 trust
host all all ::1/128 trust
host all all 0.0.0.0/0 md5Key settings:
- local: Unix domain socket connections
- host: TCP/IP connections
- ADDRESS can be hostname, CIDR notation (192.168.0.0/16), or 'all'
- METHOD: trust (no password), md5/password (with password), scram-sha-256, ident, etc.
To allow remote connections:
host all all 0.0.0.0/0 scram-sha-256Reload the configuration after editing:
sudo systemctl reload postgresql
# or send SIGHUP signal
sudo -u postgres pg_ctl reload -D /var/lib/postgresql/dataNetwork firewalls can block PostgreSQL connections. Verify port 5432 is accessible.
On Linux with UFW:
# Check current rules
sudo ufw status
# Allow PostgreSQL port (if needed)
sudo ufw allow 5432/tcp
# Allow from specific IP only (more secure)
sudo ufw allow from 192.168.1.100 to any port 5432On Linux with firewalld:
# Check allowed ports
sudo firewall-cmd --list-ports
# Allow PostgreSQL port
sudo firewall-cmd --permanent --add-port=5432/tcp
sudo firewall-cmd --reloadOn Windows (PowerShell as Administrator):
# Check existing rules
Get-NetFirewallRule | Where-Object {$_.DisplayName -like "*PostgreSQL*"}
# Create new rule
New-NetFirewallRule -DisplayName "PostgreSQL" `
-Direction Inbound -LocalPort 5432 -Protocol TCP -Action AllowCloud firewalls (AWS/Azure/GCP):
- Check security groups, network ACLs, or firewall rules
- Ensure inbound traffic on port 5432 is allowed from your client IP
- Consider using security group source restrictions instead of opening to 0.0.0.0/0
Use the psql command-line tool to test connectivity and get detailed error messages.
Basic connection test:
# Connect to localhost (default)
psql -U postgres
# Connect to specific host and port
psql -h localhost -p 5432 -U postgres -d postgres
# Connect to remote server
psql -h db.example.com -p 5432 -U postgres -d mydbWhen prompted for password, enter the database password.
Verbose connection output:
# Show detailed connection diagnostics
psql -h localhost -p 5432 -U postgres -d postgres -v ON_ERROR_STOP=1
# Even more verbose (trace libpq messages)
PGSSLMODE=require psql -h localhost -p 5432 -U postgresConnection string format alternative:
# Using connection string
psql "postgresql://postgres@localhost:5432/postgres"
# With password in URL (not recommended for security)
psql "postgresql://postgres:password@localhost:5432/postgres"Common error messages and meanings:
- could not connect to server: Connection refused - Server not running or wrong port
- could not translate host name "hostname" to address - DNS resolution failed
- is the server running on host - Server not listening on that address
- FATAL: no pg_hba.conf entry for host - Authentication rules don't allow connection
PostgreSQL has a limit on concurrent connections. If exceeded, new connections will fail.
Check current connection limit:
# Connect with superuser
psql -U postgres
# Query the max_connections parameter
SHOW max_connections;
# Check current connection count
SELECT count(*) FROM pg_stat_activity;Increase connection limit (if needed):
# Edit postgresql.conf
sudo nano /etc/postgresql/15/main/postgresql.confFind and modify:
# Default is usually 100
max_connections = 100
# Increase to allow more connections
max_connections = 200Apply the change:
sudo systemctl restart postgresqlIdentify idle or long-running connections:
-- Connect as superuser
psql -U postgres
-- View active connections
SELECT pid, usename, state, query_start, query
FROM pg_stat_activity
WHERE state != 'idle';
-- Kill long-running queries (be careful!)
SELECT pg_terminate_backend(pid)
FROM pg_stat_activity
WHERE query_start < now() - interval '1 hour';Ensure TCP/IP connections are not disabled in PostgreSQL configuration.
Check the setting:
# Connect to PostgreSQL
psql -U postgres
# Query the listen_addresses setting
SHOW listen_addresses;The output should be something like:
- localhost - Only local connections
- * - All interfaces (recommended for servers)
- 192.168.1.100 - Specific IP address
If listen_addresses is empty or unset, TCP/IP may be disabled.
Also check for SSL/TLS requirements:
-- Check SSL mode
SHOW ssl;
-- Check SSL certificate paths
SHOW ssl_cert_file;
SHOW ssl_key_file;If SSL is required but your client doesn't support it, use the sslmode parameter:
# Force non-SSL connection
psql "postgresql://localhost/postgres?sslmode=disable"
# Or set via environment
export PGSSLMODE=disable
psqlIf running PostgreSQL in Docker, special considerations apply.
Example docker-compose.yml:
version: '3.8'
services:
postgres:
image: postgres:15
environment:
POSTGRES_USER: postgres
POSTGRES_PASSWORD: password
POSTGRES_DB: mydb
ports:
- "5432:5432"
volumes:
- postgres_data:/var/lib/postgresql/data
volumes:
postgres_data:Start the container:
docker-compose up -d
# Wait a few seconds for PostgreSQL to initialize
sleep 5
# Test connection from your machine
psql -h localhost -U postgres -d mydbConnect from another Docker container:
# Use the service name (postgres) as hostname, not localhost
psql -h postgres -U postgres -d mydbCommon Docker issues:
- Port not mapped: Add "5432:5432" to ports in docker-compose
- Container not started: Run docker-compose up -d or check docker logs postgres
- Wrong hostname: Use postgres (service name) inside Docker network, localhost from host machine
- Not enough time to initialize: Add healthcheck or wait script before connecting
Debugging Docker PostgreSQL:
# Check container logs
docker-compose logs postgres
# Execute psql inside container
docker exec -it <container_name> psql -U postgres
# Check port mapping
docker port <container_name>Understanding PostgreSQL connection error codes:
PostgreSQL uses SQLSTATE (5-character error code) to classify errors. Connection-related errors all start with 08:
- 08000: sqlclient_unable_to_establish_sqlconnection
- 08001: sqlclient_unable_to_establish_sqlconnection (variant)
- 08003: connection_does_not_exist
- 08006: connection_failure
- 08P01: protocol_violation
Connection pooling for high-demand applications:
When you have many clients connecting simultaneously, consider a connection pooler:
# Using pgBouncer
[databases]
mydb = host=localhost port=5432 dbname=mydb
[pgbouncer]
listen_port = 6432
pool_mode = transaction # or session, statement
max_client_conn = 1000
default_pool_size = 25Then connect to pgBouncer on port 6432 instead of PostgreSQL directly.
Monitoring connection health in applications:
Most PostgreSQL drivers support:
- Connection timeouts: connect_timeout
- TCP keepalive: tcp_user_timeout
- Connection validation queries: Health checks before using pooled connections
- Automatic retry logic with exponential backoff
Security best practices for remote PostgreSQL:
1. Never expose PostgreSQL directly to the internet
2. Use SSH tunneling for remote access: ssh -L 5432:localhost:5432 user@server
3. Always use SSL/TLS (sslmode=require in connection string)
4. Restrict access by IP in pg_hba.conf
5. Use strong passwords or certificate-based authentication
6. Consider managed PostgreSQL services (AWS RDS, Azure Database, Google Cloud SQL) with built-in security