# javax.net.ssl.SSLPeerUnverifiedException: peer not authenticated

- **ID:** `java/ssl-peer-unverified`
- **Domain:** java
- **Category:** auth_error
- **Verification:** ai_generated
- **Fix Rate:** 85%

## Root Cause

The SSL/TLS handshake completed, but the peer's certificate chain could not be verified against the truststore, meaning the server's identity is not trusted.

## Version Compatibility

| Version | Status | Introduced | Deprecated |
|---------|--------|------------|------------|
| Java 8 | active | — | — |
| Java 11 | active | — | — |
| Java 17 | active | — | — |
| Java 21 | active | — | — |

## Workarounds

1. **Import the server's certificate into the JVM's truststore using keytool: `keytool -import -alias server -keystore $JAVA_HOME/lib/security/cacerts -file server.crt`** (90% success)
   ```
   Import the server's certificate into the JVM's truststore using keytool: `keytool -import -alias server -keystore $JAVA_HOME/lib/security/cacerts -file server.crt`
   ```
2. **Set the truststore to a custom file containing the server's CA certificate: `-Djavax.net.ssl.trustStore=/path/to/truststore.jks -Djavax.net.ssl.trustStorePassword=changeit`** (85% success)
   ```
   Set the truststore to a custom file containing the server's CA certificate: `-Djavax.net.ssl.trustStore=/path/to/truststore.jks -Djavax.net.ssl.trustStorePassword=changeit`
   ```
3. **If using a client library (e.g., OkHttp), configure the client to use a custom SSLSocketFactory that trusts the specific certificate.** (80% success)
   ```
   If using a client library (e.g., OkHttp), configure the client to use a custom SSLSocketFactory that trusts the specific certificate.
   ```

## Dead Ends

- **Set `-Djavax.net.ssl.trustStore` to a non-existent file to bypass trust validation.** — This causes a different SSL error: 'java.security.InvalidAlgorithmParameterException: the trustAnchors parameter must be non-empty', not fixing the peer verification. (90% fail)
- **Disable SSL verification entirely by setting `HttpsURLConnection.setDefaultHostnameVerifier((hostname, session) -> true)`.** — This only bypasses hostname verification; the peer certificate chain is still validated against the truststore, so the error persists. (80% fail)
- **Use a self-signed certificate but ignore all trust issues by creating a custom TrustManager that trusts all.** — While this works for development, it's a security risk and may violate organizational policies; also, some libraries like Apache HttpClient require explicit configuration. (60% fail)
