Resolving Javax.net.ssl.sslhandshakeexception: Sun.security.validator.validatorexception: Pkix Path Building Failed Error?

Better Stack Team
Updated on October 7, 2024

The javax.net.ssl.SSLHandshakeException: sun.security.validator.ValidatorException: PKIX path building failed error typically occurs when a Java application is unable to establish a secure SSL/TLS connection because it cannot validate the certificate chain presented by the remote server. This often happens when the server's SSL certificate is not trusted by the Java runtime's truststore, which is a collection of trusted CA certificates.

Here are several methods to resolve this issue:

1. Ensure the Server Certificate is Trusted

If the server is using a self-signed certificate or a certificate signed by an internal CA, you need to add that certificate (or the CA's root certificate) to the Java truststore.

Step 1: Export the Server's Certificate

You can export the certificate using a browser or command-line tool like openssl.

  • Using a Browser:
    • Visit the website.
    • Click the padlock icon and view the certificate.
    • Export the certificate in .cer or .crt format.
  • Using openssl:

     
    openssl s_client -connect yourserver.com:443 -showcerts
    

    Copy the certificate and save it in a file (e.g., server.crt).

Step 2: Import the Certificate into the Java Truststore

 
keytool -importcert -alias mycert -file server.crt -keystore $JAVA_HOME/lib/security/cacerts -storepass changeit
  • alias mycert: A unique alias name for the certificate.
  • file server.crt: The certificate file you exported.
  • keystore: The location of the Java truststore, typically located in $JAVA_HOME/lib/security/cacerts.
  • storepass changeit: The default password for the truststore.

Step 3: Verify the Certificate is in the Truststore

 
keytool -list -keystore $JAVA_HOME/lib/security/cacerts -alias mycert -storepass changeit

2. Use a Different Truststore

If you want to use a different truststore instead of modifying the default Java truststore, you can specify it using the following system properties when running your Java application:

 
-Djavax.net.ssl.trustStore=/path/to/your/truststore
-Djavax.net.ssl.trustStorePassword=yourpassword

Disabling SSL certificate validation can be risky as it makes your application vulnerable to man-in-the-middle attacks. However, if you're working in a development environment and you fully understand the implications, you can temporarily disable SSL validation.

Option 1: Programmatically

 
import javax.net.ssl.*;
import java.security.cert.X509Certificate;

public class SSLUtilities {

    public static void disableCertificateValidation() {
        try {
            TrustManager[] trustAllCerts = new TrustManager[]{
                new X509TrustManager() {
                    public X509Certificate[] getAcceptedIssuers() {
                        return null;
                    }
                    public void checkClientTrusted(X509Certificate[] certs, String authType) {
                    }
                    public void checkServerTrusted(X509Certificate[] certs, String authType) {
                    }
                }
            };

            SSLContext sc = SSLContext.getInstance("SSL");
            sc.init(null, trustAllCerts, new java.security.SecureRandom());
            HttpsURLConnection.setDefaultSSLSocketFactory(sc.getSocketFactory());
            HttpsURLConnection.setDefaultHostnameVerifier(new HostnameVerifier() {
                public boolean verify(String hostname, SSLSession session) {
                    return true;
                }
            });
        } catch (Exception e) {
            e.printStackTrace();
        }
    }
}

Call SSLUtilities.disableCertificateValidation(); before making SSL connections.

Option 2: Using JVM Arguments

You can add the following arguments to the JVM to disable certificate validation:

 
-Dcom.sun.net.ssl.checkRevocation=false
-Dcom.sun.security.enableCRLDP=false
-Dcom.sun.net.ssl.trustStoreType=Windows-ROOT

4. Ensure System Time is Correct

SSL/TLS certificates have a validity period. If your system clock is incorrect, it might cause the certificate validation to fail. Ensure that your system time and date are correct.

5. Check for Intermediate Certificates

Ensure that the server provides the full certificate chain, including any intermediate certificates. If the chain is incomplete, the Java runtime will not be able to build the trust path to a trusted root certificate.

6. Upgrade Java

Ensure you are using an up-to-date version of the Java Runtime Environment (JRE). Older versions may not include the latest CA certificates or may have other SSL/TLS bugs.

7. Use the Djavax.net.debug=ssl Option

Enable SSL debugging to get more details about what might be causing the handshake to fail:

 
java -Djavax.net.debug=ssl -jar yourapplication.jar

This will print detailed information about the SSL handshake process and may help you identify the problem.

Summary

The PKIX path building failed error typically arises due to untrusted certificates. The primary solution is to ensure the server's certificate (or its CA) is trusted by adding it to the Java truststore. If the issue persists, consider using an alternative truststore, check for intermediate certificates, or disable SSL validation (not recommended for production). Debugging SSL connections can also help diagnose the problem further.

Got an article suggestion? Let us know
Licensed under CC-BY-NC-SA

This work is licensed under a Creative Commons Attribution-NonCommercial-ShareAlike 4.0 International License.

Make your mark

Join the writer's program

Are you a developer and love writing and sharing your knowledge with the world? Join our guest writing program and get paid for writing amazing technical guides. We'll get them to the right readers that will appreciate them.

Write for us
Writer of the month
Marin Bezhanov
Marin is a software engineer and architect with a broad range of experience working...
Build on top of Better Stack

Write a script, app or project on top of Better Stack and share it with the world. Make a public repository and share it with us at our email.

community@betterstack.com

or submit a pull request and help us build better products for everyone.

See the full list of amazing projects on github