This post is about a common error that most java developers would have witnessed in their career. The problem appears with a cryptic error message “unable to find valid certification path to requested target‘’. This error message is generally printed out by the sun.security.provider.certpath.SunCertPathBuilderException class.
This is an exception handling class in Java that deals with verifying the SSL certificates of the server that the java application is trying to connect to. Below is a snippet of the log messages the developer is shown while encountering this error.
caused by: javax.net.ssl.SSLHandshakeException: sun.security.validator.ValidatorException: PKIX path building failed:sun.security.provider.certpath.SunCertPathBuilderException: unable to find valid certification path to requested target '
What makes it difficult to troubleshoot is that this exception class can be triggered in multiple situations. It can be thrown during any operation that requires accessing a service that is secured using SSL encryption. Some of the typical situations that trigger this error are listed below.
- The most common situation in which this error is faced is when a package build process tries to access the maven package repository. The typical reason is an outdated client certification configuration. It also comes to the light straight after a Java version change operation at the client-side.
- Another typical situation is during the use of client libraries provided by third-party services. When the developer tries to use the library in his code, the library tries to access its parent REST or SOAP API and throws this error. The reason, in this case, is also the lack of certificate configuration of the parent domain in the client machine. A client library like Twitter4J that helps pull tweets by accessing Twitter APIs can trigger this error if your client machine has an outdated certificate configuration.
- This error can also be seen in cases where a client application accesses a service succeed by self-signed certificates.
Out of the three situations above, the most common occurrence of this error is while dealing with the artifact build process and package management. A package repository like PackageCloud that just works all the time can relieve you from thinking about frustrating problems like these.
You can checkout PackageCloud here. Now that we understand the typical situations in which this error is found, let’s move on to understanding the root cause.
What is the problem when you see “unable to find valid certification path to requested target”
In a nutshell, the root cause of this error irrespective of the scenario you encountered it in is an invalid certificate configuration at the client machine. Fixing this error needs one to have a full understanding of what is involved in an invalid certificate configuration. As mentioned above, this error is usually thrown by Java client applications. The client application can either be a package management client or third-party library or even a custom java module.
While trying to access an API or domain secured by SSL, the Java framework checks whether the certificate used by the service is trusted. It does this by checking whether the root certificate authority who signed it is present in its internal trusted list. If it does not find mention of it, Java aborts accessing the service and throws this error. It is now straightforward to understand that a client application trying to access a service signed by a self-signed certificate will always end up in trouble.
But why does this error get thrown while trying to access third-party services from dependable providers? The reason can be either of the two listed below.
- Something that happened in your Java framework installation directory has messed up its list of trusted providers. This can even be a simple version upgrade gone wrong.
- The certificate at the third-party service may not be signed by a popular root CA or it could be signed by an intermediate CA that is not present in JRE’s trusted list.
If you are unfamiliar with the concepts of SSL encryption, terms like root CA and intermediate CA may be intimidating. Before going to the solution for the problem, let’s try to understand how these terms are important in the context of the error.
Understanding SSL encryption and certificates
An SSL certificate is the backbone of an HTTPS connection. It establishes the identity of the website or the service through a pair of public and private keys. Everything that is served by the domain is encrypted or signed by the private key and the client applications verify the identity by using the public keys. The key pair is generated by the website or the server by placing a certificate signing request with a certificate authority who is well known.
The Certificate Authority generally has a root certificate that has been approved by trust stores run by organizations like Microsoft, Google, Mozilla, etc. It uses this root certificate to provide SSL certificates. The catch here is that certificate authorities do not always use their root certificates to authorize SSL certificates. In order to mitigate their risk and avoid a single point of failure, they generate intermediate certificates using root certificates and then use these intermediate certificates to generate SSL certificates. This is called a certificate chain. This chain can be made longer by generating child certificates from root certificates and intermediate certificates.
With the introduction of chaining and intermediate CAs, the client applications now should be able to verify the authenticity of servers by checking the intermediate certificates. At times this may not work well and the user has to manually add the whole certificate chain to the trust store to ensure client applications are able to connect. The other relevant concept that needs to be understood is the self-signed certificate. These are certificates that are generated by the website or service itself without depending on a well-known certificate authority.
Naturally, these certificates can not be trusted unless there is a special relationship between the client and server. In the same entity is managing both the client and server application, self-signed certificates can be used. Since JRE does not have any mechanism for verifying a self-signed certificate, it will trust it only if the user has manually added the certificate to the trust store. Now that we understand the theory of SSL certificates, it is evident that the solution to this problem is to add the certificate of the server to the trust store. Let’s now understand how we can accomplish this.
How to solve “unable to find valid certification path to requested target”
1. The first step of troubleshooting this problem is to check whether this is indeed a certificate problem or something to do with the network. To confirm this, try accessing the URL from your favorite browser. If the browser is able to access it, then it means, the problem is with an invalid certificate configuration at the application client. If the browser is not able to access it, then the problem could be because of network configuration or a firewall.
2. Once you have confirmed that the problem is indeed with the certificate configuration, the next step is to get hold of the certificate used by the server. In the simplest of cases, this could be the root certificate, but in most cases there will be a certificate chain and intermediate CAs.
If you are using a browser, click the lock icon next to the URL bar and click on the Certificate link and click details. From the details section, the certificate can be exported using the export button. Ensure that you select DER encoded binary as the format for export.
3. An alternate way to download the certificate is to use the below command with the URL you want to access.
openssl s_client -showcerts -connect <URL:443>
The command will output all the certificates included in the chain. The output will be as follows.
CONNECTED(00000003) depth=2 C = US, O = Google Trust Services LLC, CN = GTS Root R1 verify return:1 depth=1 C = US, O = Google Trust Services LLC, CN = GTS CA 1C3 verify return:1 depth=0 CN = *.google.com verify return:1 --- Certificate chain 0 s:CN = *.google.com i:C = US, O = Google Trust Services LLC, CN = GTS CA 1C3 -----BEGIN CERTIFICATE----- O/B/H91EeIB4q+nmRO tYxFcW8qt9iyYP/rqp2q6lBmzkPLEpJH.... -----END CERTIFICATE-----
Save each of them as a file with unique names. Ensure that you copy both the BEGIN CERTIFICATE and END CERTIFICATE part.
4. The next step is to add the certificate to the trust store. This can be done using the keytool utility.
sudo keytool -importcert -keystore /usr/local/java/jdk1.8.0_60/jre/lib/security/cacerts -storepass changeit -file ~/Downloads/cert_file.crt -alias "root_cert"
While importing multiple certificates, ensure that the alias name is different for each of them. The default password for the JRE trust store is ‘changeit’. If you have changed this password, ensure to use the correct password.
Once this is done, restart your application and everything should be fine.
The error ‘unable to find valid certification path to requested target’ is a tough one to troubleshoot since it needs elaborate knowledge on SSL certificates, root CAs and intermediate CAs. This error is extremely common while dealing with package managers, automated deployment processes etc. The best way to avoid losing time stuck on such issues is to use a reliable package repository like Packagecloud that just works all the time.
You can checkout PackageCloud here.