Unable to find valid certification path to requested target - error even after cert imported

I have a Java client trying to access a server with a self-signed certificate. When I try to Post to the server, I get the following error:

unable to find valid certification path to requested target
  1. Saved my servers domain name as a root.cer file.
  2. In my Glassfish server's JRE, I ran this:
keytool -import -alias example -keystore cacerts -file root.cer 
keytool -list -v -keystore cacerts 

I am still getting the same error.

I have a feeling this is because my Glassfish is not actually reading the cacert file that I have amended but maybe some other one.

Have any of you had this issue and can push me in the right direction?

85.5k 9 9 gold badges 160 160 silver badges 358 358 bronze badges asked Feb 9, 2012 at 12:05 8,823 15 15 gold badges 44 44 silver badges 55 55 bronze badges

Just to clarify "I have a Java client trying to access a server with a self-signed certificate.": you're talking of using client-certificates that are self-signed, aren't you? Is there any specific configuration for your connector settings on Glassfish (trust store settings, in particular)?

Commented Feb 9, 2012 at 12:25

"I have a Java client trying to access a server with a self-signed certificate.": you're talking of using client-certificates that are self-signed, aren't you? - yes.

Commented Feb 9, 2012 at 13:51

I have found 2 settings in Glassfish JVM: -Djavax.net.ssl.keyStore=$/config/keystore.jks and -Djavax.net.ssl.trustStore=$/config/cacerts.jks. I now need to add by cert to one of those. Can you confirm it's the keystore I add it to?

Commented Feb 9, 2012 at 13:52

On the server, the keystore is for the server cert and its private key (keystore is for what "belongs" to local party). The truststore is for the certs used to verify trust in the remote party. You should add the client cert to your server trust store. (See this too, although Glassfish doesn't seem to be using the JRE's default location.)

Commented Feb 9, 2012 at 13:56

You can blindly accept all SLL certificates as shown in this full runnable example code - That's of course insecure!: nakov.com/blog/2009/07/16/…

Commented Jun 19, 2018 at 13:14

20 Answers 20

Unfortunately - it could be many things - and lots of app servers and other java 'wrappers' are prone to play with properties and their 'own' take on keychains and what not. So it may be looking at something totally different.

Short of truss-ing - I'd try:

java -Djavax.net.debug=all -Djavax.net.ssl.trustStore=trustStore . 

to see if that helps. Instead of 'all' one can also set it to 'ssl', key manager and trust manager - which may help in your case. Setting it to 'help' will list something like below on most platforms.

Regardless - do make sure you fully understand the difference between the keystore (in which you have the private key and cert you prove your own identity with) and the trust store (which determines who you trust) - and the fact that your own identity also has a 'chain' of trust to the root - which is separate from any chain to a root you need to figure out 'who' you trust.

all turn on all debugging ssl turn on ssl debugging The following can be used with ssl: record enable per-record tracing handshake print each handshake message keygen print key generation data session print session activity defaultctx print default SSL initialization sslctx print SSLContext tracing sessioncache print session cache tracing keymanager print key manager tracing trustmanager print trust manager tracing pluggability print pluggability tracing handshake debugging can be widened with: data hex dump of each handshake message verbose verbose handshake message printing record debugging can be widened with: plaintext hex dump of record plaintext packet print raw SSL/TLS packets 
104k 126 126 gold badges 458 458 silver badges 612 612 bronze badges answered Feb 9, 2012 at 12:16 Dirk-Willem van Gulik Dirk-Willem van Gulik 7,706 2 2 gold badges 36 36 silver badges 41 41 bronze badges

Thanks a lot! -Djavax.net.ssl.trustStore=/location_of/trustStore solved my problem and the debug info was really helpful too.

Commented Jul 19, 2016 at 23:30

java -Djavax.net.debug=all -Djavax.net.ssl.trustStore=trustStore . gives the below error: Error: Could not find or load main class .

Commented Apr 9, 2019 at 10:12

Of course you may also need to specify the truststore's password with -Djavax.net.ssl.trustStorePassword=changeit

Commented Feb 6, 2020 at 22:52 @rohith instead of . give it the path to a simple helloWorld.java . Commented Feb 21, 2023 at 13:07

Here is the solution , follow the below link Step by Step :

JAVA FILE : which is missing from the blog

/* * Copyright 2006 Sun Microsystems, Inc. All Rights Reserved. * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions * are met: * * - Redistributions of source code must retain the above copyright * notice, this list of conditions and the following disclaimer. * * - Redistributions in binary form must reproduce the above copyright * notice, this list of conditions and the following disclaimer in the * documentation and/or other materials provided with the distribution. * * - Neither the name of Sun Microsystems nor the names of its * contributors may be used to endorse or promote products derived * from this software without specific prior written permission. * * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS * IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF * LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. */ import java.io.*; import java.net.URL; import java.security.*; import java.security.cert.*; import javax.net.ssl.*; public class InstallCert < public static void main(String[] args) throws Exception < String host; int port; char[] passphrase; if ((args.length == 1) || (args.length == 2)) < String[] c = args[0].split(":"); host = c[0]; port = (c.length == 1) ? 443 : Integer.parseInt(c[1]); String p = (args.length == 1) ? "changeit" : args[1]; passphrase = p.toCharArray(); >else < System.out.println("Usage: java InstallCert [:port] [passphrase]"); return; > File file = new File("jssecacerts"); if (file.isFile() == false) < char SEP = File.separatorChar; File dir = new File(System.getProperty("java.home") + SEP + "lib" + SEP + "security"); file = new File(dir, "jssecacerts"); if (file.isFile() == false) < file = new File(dir, "cacerts"); >> System.out.println("Loading KeyStore " + file + ". "); InputStream in = new FileInputStream(file); KeyStore ks = KeyStore.getInstance(KeyStore.getDefaultType()); ks.load(in, passphrase); in.close(); SSLContext context = SSLContext.getInstance("TLS"); TrustManagerFactory tmf = TrustManagerFactory.getInstance(TrustManagerFactory.getDefaultAlgorithm()); tmf.init(ks); X509TrustManager defaultTrustManager = (X509TrustManager)tmf.getTrustManagers()[0]; SavingTrustManager tm = new SavingTrustManager(defaultTrustManager); context.init(null, new TrustManager[] , null); SSLSocketFactory factory = context.getSocketFactory(); System.out.println("Opening connection to " + host + ":" + port + ". "); SSLSocket socket = (SSLSocket)factory.createSocket(host, port); socket.setSoTimeout(10000); try < System.out.println("Starting SSL handshake. "); socket.startHandshake(); socket.close(); System.out.println(); System.out.println("No errors, certificate is already trusted"); >catch (SSLException e) < System.out.println(); e.printStackTrace(System.out); >X509Certificate[] chain = tm.chain; if (chain == null) < System.out.println("Could not obtain server certificate chain"); return; >BufferedReader reader = new BufferedReader(new InputStreamReader(System.in)); System.out.println(); System.out.println("Server sent " + chain.length + " certificate(s):"); System.out.println(); MessageDigest sha1 = MessageDigest.getInstance("SHA1"); MessageDigest md5 = MessageDigest.getInstance("MD5"); for (int i = 0; i < chain.length; i++) < X509Certificate cert = chain[i]; System.out.println (" " + (i + 1) + " Subject " + cert.getSubjectDN()); System.out.println(" Issuer " + cert.getIssuerDN()); sha1.update(cert.getEncoded()); System.out.println(" sha1 " + toHexString(sha1.digest())); md5.update(cert.getEncoded()); System.out.println(" md5 " + toHexString(md5.digest())); System.out.println(); >System.out.println("Enter certificate to add to trusted keystore or 'q' to quit: [1]"); String line = reader.readLine().trim(); int k; try < k = (line.length() == 0) ? 0 : Integer.parseInt(line) - 1; >catch (NumberFormatException e) < System.out.println("KeyStore not changed"); return; >X509Certificate cert = chain[k]; String alias = host + "-" + (k + 1); ks.setCertificateEntry(alias, cert); OutputStream out = new FileOutputStream("jssecacerts"); ks.store(out, passphrase); out.close(); System.out.println(); System.out.println(cert); System.out.println(); System.out.println ("Added certificate to keystore 'jssecacerts' using alias '" + alias + "'"); > private static final char[] HEXDIGITS = "0123456789abcdef".toCharArray(); private static String toHexString(byte[] bytes) < StringBuilder sb = new StringBuilder(bytes.length * 3); for (int b : bytes) < b &= 0xff; sb.append(HEXDIGITS[b >> 4]); sb.append(HEXDIGITS[b & 15]); sb.append(' '); > return sb.toString(); > private static class SavingTrustManager implements X509TrustManager < private final X509TrustManager tm; private X509Certificate[] chain; SavingTrustManager(X509TrustManager tm) < this.tm = tm; >public X509Certificate[] getAcceptedIssuers() < throw new UnsupportedOperationException(); >public void checkClientTrusted(X509Certificate[] chain, String authType) throws CertificateException < throw new UnsupportedOperationException(); >public void checkServerTrusted(X509Certificate[] chain, String authType) throws CertificateException < this.chain = chain; tm.checkServerTrusted(chain, authType); >> >