title: java.security.cert.CertPathValidatorException: Path does not chain with any of the trust anchors
body: <p>I am new to web services. I am getting javax.net.ssl.SSLHandshakeException while hitting one URL. The code for the Trust Manager is given below.</p>
  
  <pre><code>DatedTrustManager(Date validationDate, StorePkixParameters parameters) {
      this.validationDate = validationDate;
      this.parameters = parameters;
      try {
          validator = CertPathValidator.getInstance("PKIX");
          certFactory = CertificateFactory.getInstance("X.509");
      }
      catch(GeneralSecurityException e) {
          logger.error("error constructing CertPathValidator/CertificateFactory", e);
          throw new IllegalStateException(e);
      }
  }
  
  private void validate(X509Certificate[] chain)
          throws CertificateException {
      CertPath certPath = certFactory.generateCertPath(removeExtraCertificates(fixCertificatesOrder(chain)));
      PKIXParameters localParams = parameters.getParams();
      synchronized (validator) {
          localParams.setDate(validationDate!=null ?validationDate :new Date());
          try {
              validator.validate(certPath, localParams);
          } catch (CertPathValidatorException e) {
              logCertificatePathException(e);
              Throwable cause = e.getCause();
              if(cause instanceof CertificateException) {
                  throw (CertificateException)cause;
              }
              throw new CertificateException(e);
          } catch (InvalidAlgorithmParameterException e) {
              throw new CertificateException(e);
          }
      }
  }
  
  private X509Certificate[] fixCertificatesOrder(X509Certificate[] chain) {
  
      X509Certificate[] newChain = Arrays.copyOf(chain, chain.length);
  
      for(int i = 0; i &lt; newChain.length-1; i++) {
          X500Principal issuer = newChain[i].getIssuerX500Principal();
              boolean found = false;
              for(int j = i+2; j &lt; newChain.length; j++) {
                  if(issuer.equals(newChain[j].getSubjectX500Principal())) {
                      X509Certificate temp = newChain[i+1];
                      newChain[i+1] = newChain[j];
                      newChain[j] = temp;
                      found = true;
                      break;
                  }
              }
              if(!found) {
                  return Arrays.copyOf(newChain, i+1);
              }
          }
  
          if(!isCertificateValid(newChain[i+1])) {
              return Arrays.copyOf(newChain, i+1);
          }
      }
      return newChain;
  }
  
  private boolean isCertificateValid(X509Certificate cert) {
      try {
          if(validationDate == null) {
              cert.checkValidity();
          } else {
              cert.checkValidity(validationDate);
          }
          return true;
      }
      catch(CertificateNotYetValidException ex) {
          return false;
      }
      catch(CertificateExpiredException ex) {
          return false;
      }
  }
  
  private List&lt;X509Certificate&gt; removeExtraCertificates(X509Certificate[] chain) {
      List&lt;X509Certificate&gt; rc= new ArrayList&lt;X509Certificate&gt;(chain.length);     
      for(X509Certificate cert : chain) {
          rc.add(cert);
          X500Principal subjectX500Principal = cert.getSubjectX500Principal();
          X500Principal issuerX500Principal = cert.getIssuerX500Principal();
          if(subjectX500Principal.equals(issuerX500Principal)) {
              // remove old algorithm that is no longer supported
              // root certificate should be found in trust store
              // 6/21/11 - Opened up to all algorithms (before just cert.getSigAlgName() = "MD2withRSA" or "SHA1withRSA").
              //           Remove all root certificates and expect them to be in the trust store.
              rc.remove(rc.size()-1);
              break;
          }
      }
      return rc;
  }
  
  static private void logCertificatePathException(CertPathValidatorException e) {
      CertPath path = e.getCertPath();
      if(path!=null) {
          int idx= e.getIndex();
          if(0&lt;=idx) {
              Certificate certInError = path.getCertificates().get(idx);
              if(certInError instanceof X509Certificate) {
                  X509Certificate xcert= (X509Certificate)certInError;
                  logger.info("Certificate {} in error - {}", xcert.getSubjectX500Principal(), e.getMessage());
              }
          }
      }
  }
  
  @Override
  public void checkClientTrusted(X509Certificate chain[], String authType)
          throws CertificateException {
      validate(chain);
  }
  
  @Override
  public void checkServerTrusted(X509Certificate chain[], String authType)
          throws CertificateException {
      validate(chain);
  }
  
  @Override
  public X509Certificate[] getAcceptedIssuers() {
      return parameters.getTrustCerts().clone();
  }
  
  public Date getValidationDate() {
      return validationDate;
  }
  
  @Override
  public void checkClientTrusted(X509Certificate[] chain, String authType,
          Socket socket) throws CertificateException {
      validate(chain);
  }
  
  @Override
  public void checkClientTrusted(X509Certificate[] chain, String authType,
          SSLEngine engine) throws CertificateException {
      validate(chain);
  }
  
  @Override
  public void checkServerTrusted(X509Certificate[] chain, String authType,
          Socket socket) throws CertificateException {
      validate(chain);
  }
  
  @Override
  public void checkServerTrusted(X509Certificate[] chain, String authType,
          SSLEngine engine) throws CertificateException {
      validate(chain);
  }
  </code></pre>
  
  <p>I verified the SSL certificates and updated the trust store but still this issue is coming. Please help me out here.</p>