Q&A
Error: unable to find valid certification path to the target
Overview
When a Java app makes an HTTPS connection, it validates the server's certificate chain up to a trusted root CA stored in its truststore ($JAVA_HOME/lib/security/cacerts). If the chain can't be traced to a trusted root, Java refuses the connection with this PKIX error. It's fundamentally a trust problem, not a code bug.
graph TD
A[Java HTTPS request] --> B[Server presents certificate chain]
B --> C{Chain traces to a trusted root in cacerts?}
C -->|yes| D[Connection succeeds]
C -->|no| E[PKIX path building failed:<br/>unable to find valid certification path]
E --> F[Fix: import cert/CA into truststore]
style E fill:#1e1b4b,color:#fff
Why It Happens
Common causes:
- The server uses a self-signed certificate.
- The certificate is issued by an internal/corporate CA not in Java's default truststore.
- An incomplete chain - the server doesn't send intermediate certificates, so Java can't build the path.
- An expired or misconfigured certificate.
- A corporate TLS-inspecting proxy re-signs traffic with a CA your JVM doesn't trust.
The Standard Fix: Import the Certificate
Add the server's certificate (ideally the CA root/intermediate) to Java's truststore using keytool.
Step 1 - obtain the certificate. For example with openssl:
openssl s_client -connect example.com:443 -showcerts </dev/null \
| openssl x509 -outform PEM > server.crt
Step 2 - import it into the truststore:
keytool -importcert \
-alias example-server \
-file server.crt \
-keystore "$JAVA_HOME/lib/security/cacerts" \
-storepass changeit # default password for cacerts
After importing the trusted certificate (or, better, its issuing CA), Java can build a valid path and the error disappears. Prefer importing the CA root so all certificates it issues are trusted, rather than pinning one server cert.
Using a Custom (Application) Truststore
Instead of modifying the JDK's global cacerts, point your app at its own truststore:
java -Djavax.net.ssl.trustStore=/path/to/mytruststore.jks \
-Djavax.net.ssl.trustStorePassword=secret \
-jar app.jar
This keeps your changes isolated from the JDK installation (which is wiped on upgrades).
Diagnosing
Enable TLS debug logging to see exactly where path-building fails:
java -Djavax.net.debug=ssl:handshake -jar app.jar
Also verify the server actually sends its full chain (missing intermediates is a common server-side misconfiguration - fix the server rather than the client when possible).
What NOT to Do
The dangerous "fix" is disabling certificate validation entirely (a trust-all TrustManager that accepts any certificate). Don't do this in production - it removes protection against man-in-the-middle attacks, defeating the purpose of TLS. The error is doing its job: refusing an unverifiable connection. Solve trust properly by importing the correct CA.
Why This Matters in Interviews
This is a practical Java/security troubleshooting question. Demonstrate that you understand it's a trust-chain validation failure (not a code bug): Java couldn't trace the server cert to a trusted root in its truststore. Explain the proper fix (keytool import of the CA into cacerts or a custom truststore), how to diagnose (javax.net.debug, checking for a complete chain), and - critically - why disabling validation is the wrong fix (reintroduces MITM risk). Mentioning incomplete-chain and corporate-proxy causes shows real experience.
Common Pitfalls
- "Fixing" it by trusting all certificates → opens the app to man-in-the-middle attacks.
- Importing one server cert instead of the CA root (breaks again when the server cert rotates).
- Editing the JDK's
cacertsand losing the change on a JDK upgrade (use an app truststore). - Overlooking that the server is misconfigured (not sending intermediates) and patching the client instead.
- Forgetting the default
cacertspassword ischangeit.
References
- Java
keytool: https://docs.oracle.com/en/java/javase/17/docs/specs/man/keytool.html - JSSE Reference Guide (truststores, debugging): https://docs.oracle.com/en/java/javase/17/security/java-secure-socket-extension-jsse-reference-guide.html