title: Certificate path discovery in Java
body: <p>I try to make an https connection via java build-in functionality for that (<code>HttpURLConnection</code>). But I get this exception:</p>
  
  <pre><code>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
  at com.sun.net.ssl.internal.ssl.Alerts.getSSLException(Alerts.java:174)
  ...
  ...
  </code></pre>
  
  <p>My Certificate chain is:</p>
  
  <p><code>Root certificate -&gt; Intermediate certificate -&gt; Web server certificate</code></p>
  
  <p>The used certificate is correct by the meaning of "Path discovery". The trust anchor is the Root certificate, which is imported in java's keystore on my system. The intermediate certificate is not... BUT</p>
  
  <ol>
  <li>Intermediate certificate is signed by the root, who I trust - so I trust on the intermediate too.</li>
  <li>Web server certificate is signed with Intermediate certificate, which I trust (point 1)</li>
  </ol>
  
  <p>So the validation has to pass successfully? Do I getting something wrong?</p>
  
  <p>Somewhere i read this:</p>
  
  <blockquote>
    <p>Browsers can do auto-discovery, server to server doesn't.</p>
  </blockquote>
  
  <p>but absence of this functionality is very basic. Are there clear way of doing this <a href="http://en.wikipedia.org/wiki/Certification_path_validation_algorithm" rel="nofollow">auto-discovery</a>?</p>
  
  <p>*<em>*</em> Update</p>
  
  <p>Yes, this was the issue, GPI. I was confused, because browsers could validate the server certificate but java application could not.
  The cause of that behaviour was:</p>
  
  <ul>
  <li>the server sends only final certificate, not the whole certificate
  chain;</li>
  <li>the certificate was recently bought and it was signed with relatively
  new intermediate certificate;</li>
  <li>the browsers have relatively up-to-date list of certificates
  including the intermediate certificate;</li>
  <li>java have relative not up-to-date list of certificates, and
  intermediate certificate was not inside.</li>
  <li>browsers validate the final certificate over the intermediate
  certificate java could not check the certificate chain because: 1.
  the chain was not sent; 2. the signer of final certificate (the
  intermediate one) was not a trust anchor.</li>
  </ul>
  
  <p>The solutions could be: </p>
  
  <ul>
  <li>server to return the whole certificate chain</li>
  <li>the intermediate certificate to be added in java trust store</li>
  </ul>