javax.net.ssl.SSLHandshakeException
ID: java/ssl-handshake-exception
Version Compatibility
| Version | Status | Introduced | Deprecated | Notes |
|---|---|---|---|---|
| 17 | active | — | — | — |
Root Cause
SSLHandshakeException occurs when the TLS/SSL handshake between client and server fails. Common causes: untrusted certificate (self-signed or expired), certificate hostname mismatch, incompatible TLS versions, or missing CA certificates in the Java truststore.
genericWorkarounds
-
88% success Import the server's certificate or CA certificate into the Java truststore
1. Download the server certificate: 'openssl s_client -connect host:443 -showcerts'. 2. Save the certificate to a file (PEM format). 3. Import into the Java truststore: 'keytool -importcert -alias myserver -file server.crt -keystore $JAVA_HOME/lib/security/cacerts -storepass changeit'. 4. Alternatively, create a custom truststore and pass it via -Djavax.net.ssl.trustStore=/path/to/truststore.jks. 5. For Spring Boot: configure server.ssl.trust-store properties.
-
85% success Update the JDK's CA certificates and ensure the server certificate is valid and not expired
1. Check certificate validity: 'openssl s_client -connect host:443 | openssl x509 -noout -dates'. 2. Verify the certificate chain is complete — the server must send all intermediate certificates. 3. Update the JDK to the latest patch version, which includes updated CA certificates. 4. If the server certificate's CN or SAN does not match the hostname, fix the server configuration or use the correct hostname. 5. For TLS version issues: check which TLS versions the server supports with 'nmap --script ssl-enum-ciphers -p 443 host'.
Dead Ends
Common approaches that don't work:
-
Disabling SSL/TLS certificate verification entirely with a TrustManager that trusts all certificates
55% fail
A TrustManager that accepts all certificates disables the fundamental security guarantee of TLS. This makes the application vulnerable to man-in-the-middle attacks where an attacker can intercept and modify all encrypted traffic. This is never acceptable in production and should be avoided even in development.
-
Downgrading TLS version to TLSv1.0 or TLSv1.1 to avoid handshake failures
70% fail
TLSv1.0 and TLSv1.1 have known security vulnerabilities and are disabled by default in JDK 17+. Downgrading TLS version opens the connection to BEAST, POODLE, and other attacks. Modern servers increasingly reject TLSv1.0/1.1 connections entirely.