This problem is due to incomplete trust path for the server certificate: the server certificate is probably not trusted by the client.
Usually the fix is to import the server certificate into the client trust store. The default trustStore is in jre/lib/security/cacerts but is is a better practice to use your own keystore
You can create an SSLSocketFactory
and add to your connection before connecting or apply to all connections using the static method
HttpsURLConnection.setDefaultSSLSocketFactory(sslFactory);
This is an example to create the socket factory
/* Load the keyStore that includes the server cert as a "trusted" entry. */
KeyStore keyStore = ...
TrustManagerFactory tmf =
TrustManagerFactory.getInstance(TrustManagerFactory.getDefaultAlgorithm());
tmf.init(keyStore);
SSLContext ctx = SSLContext.getInstance("TLS");
ctx.init(null, tmf.getTrustManagers(), null);
sslFactory = ctx.getSocketFactory();
Example of loading the keyStore
KeyStore keyStore = KeyStore.getInstance(KeyStore.getDefaultType());
keyStore.load(trustStore, trustStorePassword);
trustStore.close();
The trust store can also be configured using system properties
System.setProperty("javax.net.ssl.trustStore", "pathtoyourjavakeystorefile");
System.setProperty("javax.net.ssl.trustStorePassword", "password");
The simplest way to create the key store file is using the GUI tool Portecle. New KeyStore > Import Trusted certificates
You can import the root certificate of the chain if you want to 'trust' all certificates from root, or import only the server certificate. For a self-signed certificate, import it directly