This error occurs when the PostgreSQL server and client have incompatible TLS/SSL protocol versions. The server rejects the connection because the client's TLS version doesn't match the server's minimum or maximum allowed versions. Update your client software or adjust server SSL configuration to fix this.
PostgreSQL uses TLS (Transport Layer Security) to encrypt connections. When a client attempts to connect, the server and client must negotiate a compatible TLS protocol version. If they don't have overlapping supported versions, the connection fails with this 'wrong version number' error. This commonly happens when clients using older TLS 1.0/1.1 try to connect to PostgreSQL 13+, which defaults to requiring TLS 1.2 or higher for security compliance.
Check what TLS versions your PostgreSQL server is configured to accept:
# Connect locally as superuser
sudo -u postgres psqlThen run:
SHOW ssl_min_protocol_version;
SHOW ssl_max_protocol_version;Common output:
- TLSv1.2 (default in PostgreSQL 13+)
- TLSv1.3 (if explicitly configured)
Note these values for comparison with your client.
Verify what TLS versions your client supports:
# Check OpenSSL version
openssl version
# List supported TLS versions
openssl s_client -h 2>&1 | grep -i "\-tls"
# Or check OpenSSL capabilities
openssl ciphers -v | grep TLSRequired OpenSSL versions for TLS support:
- TLS 1.2: OpenSSL 1.0.1+ (2012)
- TLS 1.3: OpenSSL 1.1.1+ (2018)
If you have an older OpenSSL version, your client cannot connect to PostgreSQL 13+.
The easiest fix is to upgrade your PostgreSQL client or driver to a recent version that supports TLS 1.2+:
# Update psql client (PostgreSQL)
sudo apt-get update && sudo apt-get install --only-upgrade postgresql-client
# Or for Homebrew on macOS
brew upgrade postgresql
# Update Node.js drivers
npm update pg node-postgres
# Update Python drivers
pip install --upgrade psycopg2 or psycopg[binary]
# Update Java JDBC driver
# Download latest version from https://jdbc.postgresql.orgAlternatively, update your application language/runtime:
# Update Node.js
nvm install node
# Update Python
python3 --version # Check current
pip install --upgrade pythonIf you cannot update clients immediately, you can temporarily lower the server's minimum TLS requirement. Warning: TLS 1.0 and 1.1 are deprecated for security reasons.
Edit your PostgreSQL configuration file (usually /etc/postgresql/VERSION/main/postgresql.conf):
sudo nano /etc/postgresql/VERSION/main/postgresql.confFind or add:
ssl_min_protocol_version = 'TLSv1.0' # or TLSv1.1 for slightly better security
ssl = onThen reload PostgreSQL:
sudo systemctl reload postgresqlBetter approach: Set it to TLS 1.1 temporarily while upgrading clients:
ssl_min_protocol_version = 'TLSv1.1'Some clients allow you to force a specific TLS version. Examples:
psql command line:
psql -h db.example.com -U user -d dbname -v sslmode=requireOpenSSL s_client (for testing):
openssl s_client -connect db.example.com:5432 -tls1_2Node.js (node-postgres):
const { Pool } = require('pg');
const pool = new Pool({
host: 'db.example.com',
port: 5432,
user: 'user',
password: 'password',
database: 'dbname',
ssl: {
rejectUnauthorized: false,
minVersion: 'TLSv1.2' // Force TLS 1.2
}
});Python (psycopg2):
import psycopg2
import ssl
ssl_context = ssl.SSLContext(ssl.PROTOCOL_TLSv1_2)
conn = psycopg2.connect(
host='db.example.com',
user='user',
password='password',
sslmode='require',
sslrootcert='/path/to/ca.crt'
)Use OpenSSL to test if your client and server can negotiate a common TLS version:
openssl s_client -connect db.example.com:5432 -starttls postgresLook for output like:
SSL-Session:
Protocol : TLSv1.2
Cipher : ECDHE-RSA-AES256-GCM-SHA384
Session-ID: ...If the connection fails, you'll see:
no ciphers available
error:...This confirms the TLS version mismatch. If successful, it proves a common TLS version exists.
If updating client and server TLS versions doesn't help, verify that proxies, load balancers, or firewalls aren't interfering:
# Test direct connection (if possible)
telnet db.example.com 5432
# Test connection through proxy/jumphost
telnet proxy.internal:5432
# Verify firewall rules allow SSL traffic
sudo ufw status | grep 5432
# or
sudo iptables -L -n | grep 5432Some firewalls or proxies split SSL frames or buffer handshake packets incorrectly. If this is the case:
- Whitelist the PostgreSQL port (5432) for direct traffic
- Use a tunnel or VPN instead of a proxy
- Contact your network administrator to allow unmodified SSL passthrough
If your connection uses client-side certificates, verify they're valid and match the server's requirements:
# Check certificate expiration
openssl x509 -in /path/to/client.crt -text -noout | grep -A2 'Validity'
# Check certificate format
file /path/to/client.crt
# Verify certificate chain
openssl verify -CAfile /path/to/ca.crt /path/to/client.crtExpired or mismatched certificates can cause SSL handshake failures. Regenerate certificates if needed and ensure the server's ssl_cert_file and ssl_key_file point to valid files.
TLS Negotiation: When a client connects, both sides send a list of supported TLS versions and ciphers. If there's no overlap, the connection fails. PostgreSQL 13+ removed TLS 1.0 and 1.1 support entirely, making this a hard requirement. OpenSSL Upgrade Strategy: If your system has an ancient OpenSSL (< 1.0.1), consider upgrading the entire operating system or using a container (Docker) with a modern base image. Connection Poolers: Tools like PgBouncer or pgpool may be outdated and not support modern TLS versions. Check their version and upgrade if necessary. Docker Considerations: If PostgreSQL runs in Docker, ensure the base image (Alpine, Ubuntu, etc.) has a current OpenSSL version. RDS/Managed Services: For AWS RDS, Azure Database, or GCP Cloud SQL, you typically cannot adjust ssl_min_protocol_version. Update clients instead. Corporate Networks: Large organizations may have TLS interception proxies. Work with your security team to verify the proxy supports TLS 1.2+ and allow it through firewall rules. Testing Tool: Use openssl s_client -starttls postgres -connect host:5432 -tlsv1_2 to simulate connections and debug TLS issues.
insufficient columns in unique constraint for partition key
How to fix "insufficient columns in unique constraint for partition key" in PostgreSQL
ERROR 42501: must be owner of table
How to fix "must be owner of table" in PostgreSQL
trigger cannot change partition destination
How to fix "Trigger cannot change partition destination" in PostgreSQL
SSL error: certificate does not match host name
SSL error: certificate does not match host name in PostgreSQL
No SSL connection
No SSL connection to PostgreSQL