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.
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
ERROR: syntax error at end of input
Syntax error at end of input in PostgreSQL
Bind message supplies N parameters but prepared statement requires M
Bind message supplies N parameters but prepared statement requires M in PostgreSQL
Multidimensional arrays must have sub-arrays with matching dimensions
Multidimensional arrays must have sub-arrays with matching dimensions
ERROR: value too long for type character varying
Value too long for type character varying
insufficient columns in unique constraint for partition key
How to fix "insufficient columns in unique constraint for partition key" in PostgreSQL