// Complete error message
javax.net.ssl.SSLHandshakeException: PKIX path building failed: sun.security.provider.certpath.SunCertPathBuilderException: unable to find valid certification path to requested target
This error means that during the SSL/TLS handshake process, the client is unable to verify the server's SSL certificate. The reasons for this are:
- Server certificate not trusted by the client: The server's SSL certificate may not be issued by a trusted certificate authority (CA) that the client recognizes, or the certificate may have expired.
- Network issues: In some cases, if there are problems with the network connection between the client and server, it can also cause the SSL handshake to fail.
Solution regarding certificates#
The solution lies on the server side, but usually we call other people's APIs, and we can't modify the SSL certificate of the other party, right?
Self-solution#
The self-solution is to ignore SSL certificate verification, but this will reduce security and is not recommended for use, unless absolutely necessary.
// Create an OkHttpClient that does not require SSL verification
public static OkHttpClient getClient() throws NoSuchAlgorithmException, KeyManagementException {
TrustManager[] trustManagers = new TrustManager[]{
new X509TrustManager() {
@Override
public void checkClientTrusted(X509Certificate[] chain, String authType) {
}
@Override
public void checkServerTrusted(X509Certificate[] chain, String authType) {
}
@Override
public X509Certificate[] getAcceptedIssuers() {
return new X509Certificate[0];
}
}
};
SSLContext sslContext = SSLContext.getInstance("SSL");
sslContext.init(null, trustManagers, new SecureRandom());
final OkHttpClient client = new OkHttpClient.Builder()
.sslSocketFactory(sslContext.getSocketFactory(), (X509TrustManager) trustManagers[0])
.hostnameVerifier((s, sslSession) -> true)
.build();
return client;
}
private final OkHttpClient client = getClient();
// Now we have an OkHttpClient object that ignores SSL certificate verification