<!-- https://pkizerotohero.com/errors/java-pkix-path-building-failed/ | Markdown mirror of the HTML page | PKI Zero to Hero, by Duyutech BV -->

> Fix Java's PKIX path building failed: unable to find valid certification path. Import the right root into the JDK's cacerts, or fix the server chain.

Source: https://pkizerotohero.com/errors/java-pkix-path-building-failed/ · Last reviewed: 2026-10-20

- Java

# PKIX path building failed … unable to find valid certification path to requested target

Also seen in: Maven, Gradle, Spring Boot, Jenkins, IntelliJ IDEA, Kafka clients, JDBC drivers, Kotlin, Scala

**In one sentence:**

Java found no path to a root in the JDK's cacerts: usually a company or proxy root was never imported, or the server leaves out its intermediate.

[Check yours: Chain checker](https://pkizerotohero.com/tools/chain/)

## Where you see it

In any Java program that opens an HTTPS or TLS connection: `HttpClient`, `HttpsURLConnection`, Apache HttpClient, OkHttp, JDBC drivers, Kafka clients, and tools such as Maven, Gradle and Jenkins. A typical stack trace, shortened:

```text
javax.net.ssl.SSLHandshakeException: PKIX path building failed: sun.security.provider.certpath.SunCertPathBuilderException: unable to find valid certification path to requested target
	at java.base/sun.security.ssl.Alert.createSSLException(...)
	...
Caused by: sun.security.validator.ValidatorException: PKIX path building failed: sun.security.provider.certpath.SunCertPathBuilderException: unable to find valid certification path to requested target
	...
Caused by: sun.security.provider.certpath.SunCertPathBuilderException: unable to find valid certification path to requested target
```

Newer Java releases (JDK 23 and later, 21.0.9 and later, 17.0.19 and later) put the TLS alert in front: `javax.net.ssl.SSLHandshakeException: (certificate_unknown) PKIX path building failed: …`. Build tools wrap it in their own message, but the `PKIX path building failed` part is always there. The texts come from OpenJDK’s [`PKIXValidator`](https://github.com/openjdk/jdk/blob/master/src/java.base/share/classes/sun/security/validator/PKIXValidator.java) and [`SunCertPathBuilder`](https://github.com/openjdk/jdk/blob/master/src/java.base/share/classes/sun/security/provider/certpath/SunCertPathBuilder.java).

## What it means

PKIX is the name of the X.509 path validation rules in [RFC 5280](https://www.rfc-editor.org/rfc/rfc5280#section-6). Java tried to build a [certificate chain](https://pkizerotohero.com/handbook/glossary/#certificate-chain) from the server’s certificate to a trusted [root certificate](https://pkizerotohero.com/handbook/glossary/#root-certificate) and found none. Java uses its own [trust store](https://pkizerotohero.com/handbook/glossary/#trust-store), the `cacerts` file inside the JDK (or `jssecacerts` next to it, if that file exists), not the Windows or macOS store. It also does not download a missing intermediate: that feature is off by default ([Java PKI Programmer’s Guide](https://docs.oracle.com/en/java/javase/21/security/java-pki-programmers-guide.html)). So a site that works in the browser can fail in Java.

## Likely causes

### A company or proxy root is not in the JDK’s cacerts

The most common cause at work: internal servers use a company CA, or a [TLS-inspection](https://pkizerotohero.com/handbook/glossary/#tls-inspection) proxy re-signs public sites such as Maven Central. Check who issued the certificate:

```bash
openssl s_client -connect repo.example.com:443 -servername repo.example.com -showcerts </dev/null 2>/dev/null | grep -E '^ [0-9]+ s:|^   i:'
```

Find the JDK that actually runs the failing program, and whether its `cacerts` holds the root:

```bash
java -XshowSettings:properties -version 2>&1 | grep java.home
keytool -list -v -cacerts -storepass changeit | grep -i "Owner:.*Example Corp"
```

**Fix:** import the root (PEM or DER) into that JDK’s `cacerts`. `-cacerts` works from JDK 9; `changeit` is the default password on JDK 17 and older and on Debian and Ubuntu, while newer JDK builds (such as Temurin 18 and later) ship `cacerts` without one ([keytool documentation](https://docs.oracle.com/en/java/javase/21/docs/specs/man/keytool.html)). Use `sudo` or an administrator terminal for a system-wide JDK:

```bash
keytool -importcert -cacerts -alias example-corp-root -file corp-root.pem -storepass changeit -noprompt
```

Watch out for several JDKs on one machine: the IDE’s bundled runtime, Gradle toolchains, the `JAVA_HOME` that Maven uses, and the JDK inside a container image are all separate. A JDK update also replaces `cacerts`.

On Debian and Ubuntu (with `ca-certificates-java`) and on RHEL and Fedora, the distribution’s own OpenJDK builds `cacerts` from the system store, so adding the root with `update-ca-certificates` or `update-ca-trust extract` covers Java too.

To keep the change out of the JDK, give the application its own trust store. Start from a copy of `cacerts`, because setting `javax.net.ssl.trustStore` replaces the default store completely:

```bash
cp "$JAVA_HOME/lib/security/cacerts" app-truststore
keytool -importcert -keystore app-truststore -storepass changeit -alias example-corp-root -file corp-root.pem -noprompt
java -Djavax.net.ssl.trustStore=app-truststore -Djavax.net.ssl.trustStorePassword=changeit -jar app.jar
```

If a `jssecacerts` file exists in the JDK’s `lib/security` folder, Java uses it instead of `cacerts`, so import there or remove the stale file. For Maven, pass the same properties in `MAVEN_OPTS`; for Gradle, as `systemProp.javax.net.ssl.trustStore=…` lines in `gradle.properties`.

### The server leaves out its intermediate

Count the certificates the server sends:

```bash
openssl s_client -connect repo.example.com:443 -servername repo.example.com -showcerts </dev/null 2>/dev/null | grep -c 'BEGIN CERTIFICATE'
```

`1` means the [intermediate certificate](https://pkizerotohero.com/handbook/glossary/#intermediate-certificate) is missing. Java can be told to fetch it through AIA (`com.sun.security.enableAIAcaIssuers`), but that only hides a server mistake. Fix it on the server: serve the certificate followed by the intermediate (`fullchain.pem` in nginx, `SSLCertificateFile` with the chain in Apache, the intermediate store on IIS, the chain field on load balancers). See [verify error:num=21](https://pkizerotohero.com/errors/openssl-verify-error-21/).

### Related: an expired certificate

If the message is `PKIX path validation failed: java.security.cert.CertPathValidatorException: validity check failed`, with `CertificateExpiredException: NotAfter: …` as the cause, the chain is complete but a certificate has expired. Renew it, or check the client’s clock: see [certificate has expired](https://pkizerotohero.com/errors/openssl-certificate-has-expired/).

### The JDK is old

An old JDK ships an old `cacerts` that may lack newer public roots. Update to a current patch release of your Java version.

Warning

Why a trust-all TrustManager is a trap

A `TrustManager` that accepts every certificate, `-Dmaven.wagon.http.ssl.insecure=true`, or “skip certificate validation” options in CI plugins make the error disappear by trusting anyone. For build tools that means downloading dependencies, and running their code, from whoever intercepts the connection. Import the one root you need instead.

## Check yours

*Interactive tool: Chain checker (runs in the browser at [/tools/chain/](https://pkizerotohero.com/tools/chain/))*

Paste the certificates from `openssl s_client -showcerts`. The checker shows whether a link is missing or the chain ends at a root you still need to import.

## Learn why

- [Who do we trust? CAs, trust stores and self-signed certificates](https://pkizerotohero.com/handbook/trust-stores/): why Java has its own store.
- [Certificate chains and path validation](https://pkizerotohero.com/handbook/certificate-chains/): what “path building” means.
- Related: [No subject alternative names matching IP address … found](https://pkizerotohero.com/errors/java-no-subject-alternative-names/).
- See also: [CertPathValidatorException: validity check failed](https://pkizerotohero.com/errors/java-certificate-expired/) and, on Android, [Trust anchor for certification path not found](https://pkizerotohero.com/errors/android-trust-anchor-not-found/).

**Early edition.** Checked against the standards; an independent expert review is in progress. Found a mistake? [Tell us](https://pkizerotohero.com/contact/?topic=content-error&page=/errors/java-pkix-path-building-failed/).

Last reviewed 20 October 2026Edition 0.9

## Learn why it happens

- [Chapter 12: Who do we trust? CAs, trust stores and self-signed certificates](https://pkizerotohero.com/handbook/trust-stores/)
- [Chapter 13: Certificate chains and path validation](https://pkizerotohero.com/handbook/certificate-chains/)

## Fix it step by step

- [How to check the certificate chain a server sends](https://pkizerotohero.com/guides/check-remote-certificate-chain/)
- [How to create a CSR with Java keytool](https://pkizerotohero.com/guides/create-csr-java-keytool/)
- [How to convert PFX (PKCS #12) to PEM and back](https://pkizerotohero.com/guides/convert-pfx-pem/)
- [How to convert a Java keystore (JKS) to PKCS #12](https://pkizerotohero.com/guides/convert-jks-pkcs12/)
- [How to build the full chain file your server needs](https://pkizerotohero.com/guides/build-fullchain/)
- [How to work behind a TLS-inspecting corporate proxy, safely](https://pkizerotohero.com/guides/corporate-proxy-certificates/)
- [How to add a CA to a Java trust store (cacerts)](https://pkizerotohero.com/guides/add-root-ca-java/)
- [How to install a certificate in Apache httpd](https://pkizerotohero.com/guides/install-certificate-apache/)
- [How to install a certificate in Tomcat and other Java servers](https://pkizerotohero.com/guides/install-certificate-tomcat/)

## Everything on this topic

- [Chains and trust stores](https://pkizerotohero.com/topics/chains-and-trust/)
