SSL / TLS connection errors
The error surface around TLS spans two layers: the JDK’s certificate /
hostname code (which raises generic SSLHandshakeExceptions) and
pgJDBC’s own validators and key loaders (which raise
PSQLExceptions with project-specific wording). This page lists the
patterns you are most likely to see, paired with the property change
that resolves each one.
For the underlying setup (picking an sslmode, where keys and
certificates live on disk, how to provide a custom socket factory),
see SSL / TLS
. For the safest
defaults on a fresh project, see the
Configure SSL/TLS (in Quick start)
.
PKIX path building failed
Full message, from the JDK (not pgJDBC):
javax.net.ssl.SSLHandshakeException: PKIX path building failed:
sun.security.provider.certpath.SunCertPathBuilderException: unable
to find valid certification path to requested target
The server’s certificate chain does not terminate at a CA the JVM trusts. Two paths to a fix:
- Hand pgJDBC the CA explicitly. Set
sslrootcertto a PEM file containing the CA (or chain) that signed the server certificate. This keeps the trust decision in your connection string and is the right choice for self-signed and internal CAs. - Import the CA into the JVM truststore. Useful when many JVM processes need to trust the same CA. The recipe lives in SSL / TLS § Configuring the Client .
sslmode=require does not validate the chain (see the install
page’s callout
),
so the error only fires under verify-ca and verify-full. If
you see it under require, the JVM is enforcing validation through
some other path (a SocketFactory, a security provider, an
-Djavax.net.ssl.trustStore system property).
The hostname X could not be verified by hostnameverifier Y
pgJDBC’s MakeSSL wraps the JDK’s hostname check; the underlying
message in the log will be one of:
Server name validation failed: hostname X does not match common name YServer name validation failed: certificate for hostname X has no DNS subjectAltNames…Hostname X is invalid
The server certificate’s Subject Alternative Names (or, as a fallback, its Common Name) do not include the host you wrote in the JDBC URL. Three resolutions, in decreasing preference:
- Fix the certificate. Issue a new server certificate whose SAN list contains every name clients use (DNS name, alias, public IP if you connect by IP). RFC 6125 / SAN is the modern requirement; CN-only certificates are accepted only as a fallback and are considered legacy.
- Connect by a name the certificate covers. If the certificate
lists
db.example.comand you connect with the IP, switch the URL to the hostname. - Drop to
sslmode=verify-ca. This still validates the chain but skips hostname matching. Accept it only when the connection target is not network-attacker-reachable (a Unix bridge, an in-cluster ClusterIP). On the public internetverify-cadoes not protect against an attacker who can present a certificate signed by your CA.
The server does not support SSL
Raised by ConnectionFactoryImpl when the client requires SSL
(sslmode=require or stricter) but the server has no SSL listener.
Likely causes:
sslis disabled inpostgresql.conf. Thepg_hba.confhostsslrules also have no effect when the listener is off.- The connection landed on a non-TLS port (PgBouncer / connection
pooler with
server_tls_sslmode = disable). - The PostgreSQL distribution was built without OpenSSL. Common in some container images.
Confirm with psql "host=… sslmode=require". If psql succeeds, the
problem is on the JDBC side (custom socket factory, security
provider). If psql also fails, it is genuinely a server-side issue.
SSL key file errors
Common messages from the pgJDBC SSL key loaders include:
Could not open SSL certificate file <path>Could not read SSL key file <path>Loading the SSL certificate <path> into a KeyManager failed.Could not initialize PEMKeyManager.Could not load the private keyCould not load cert chain
Together they cover the disk / format problem space:
- File not found / unreadable. Path is wrong or the JVM lacks
read permission. The defaults are
${user.home}/.postgresql/postgresql.crt,…/postgresql.pk8,…/root.crt; override withsslcert,sslkey,sslrootcertto be explicit. - Wrong key format. pgJDBC selects the key loader from the
sslkeyfilename:.p12/.pfxuse the PKCS-12 loader,.key/.pemuse the PEM loader, and other extensions use the PKCS-8 DER loader. Recent OpenSSL versions no longer support the older PKCS-8 conversion recipe, so PKCS-12 is the most portable choice. See SSL / TLS for theopenssl pkcs12 -exportrecipe. - PKCS-12 alias mismatch. When generating the bundle, the alias
passed to
openssl pkcs12 -export -name <alias>must beuser, otherwise pgJDBC won’t find it in the keystore. Thecertdir/Makefilein the repository carries a working example.
SSL-related connection properties
All TLS knobs grouped together:
| Name | Type | Default | Versions | Description |
|---|---|---|---|---|
channelBinding | enum | prefer |
| This option controls the client’s use of channel binding. |
pemKeyAlgorithm | string | RSA |
| Algorithm of the PEM key |
ssl | string | — |
| Control use of SSL (any non-null value causes SSL to be required) |
sslcert | string | — |
| The location of the client’s SSL certificate |
sslfactory | class | org.postgresql.ssl.LibPQFactory |
| Provide a SSLSocketFactory class when using SSL. |
sslfactoryarg | string | — |
| Argument forwarded to constructor of SSLSocketFactory class. |
sslhostnameverifier | class | — |
| A class, implementing javax.net.ssl.HostnameVerifier that can verify the server |
sslkey | string | — |
| The location of the client’s PKCS#8 SSL key |
sslmode | enum | — |
| Parameter governing the use of SSL |
sslNegotiation | enum | postgres |
| This option controls whether the driver will perform its protocol negotiation to request encryption from the server or will just directly make a standard SSL connection. Traditional PostgreSQL protocol negotiation is the default and the most flexible with different server configurations. If the server is known to support direct SSL connections then the latter requires one fewer round trip reducing connection latency and also allows the use of protocol agnostic SSL network tools. |
sslpassword | string | — |
| The password for the client’s ssl key (ignored if sslpasswordcallback is set) |
sslpasswordcallback | class | — |
| A class, implementing javax.security.auth.callback.CallbackHandler that can handle PasswordCallback for the ssl password. |
sslResponseTimeout | intmilliseconds | 5000 |
| Time in milliseconds we wait for a response from the server after requesting SSL upgrade |
sslrootcert | string | — |
| The location of the root certificate for authenticating the server. |
Related
- SSL / TLS : setup-side documentation; this page is the diagnostic complement.
- Configure SSL/TLS (in Quick start)
:
the recommended-default combination of
sslmode=verify-full,sslrootcert, andchannelBinding=require.