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

> Fix Java's validity check failed and CertificateExpiredException: read the NotAfter date, renew and reload the certificate, or correct the clock.

Source: https://pkizerotohero.com/errors/java-certificate-expired/ · Last reviewed: 2026-10-20

- Java
- Exact text checked with the real tool

# CertPathValidatorException: validity check failed

Also seen in: Spring, Apache HttpClient, Maven, Gradle, Tomcat, Kafka clients, JDBC drivers

**In one sentence:**

Java found a path to a trusted root, but a certificate on it is outside its validity dates: usually the server's certificate expired, sometimes the JVM's clock is wrong.

[Check yours: Certificate decoder](https://pkizerotohero.com/tools/decoder/)

## Where you see it

In any Java client that opens an HTTPS or other TLS connection, wrapped by frameworks such as Spring, Apache HttpClient, JDBC drivers and build tools. The root cause is at the bottom of the stack trace:

```text
javax.net.ssl.SSLHandshakeException: (certificate_expired) PKIX path validation failed: java.security.cert.CertPathValidatorException: validity check failed
	...
Caused by: sun.security.validator.ValidatorException: PKIX path validation failed: java.security.cert.CertPathValidatorException: validity check failed
	...
Caused by: java.security.cert.CertPathValidatorException: validity check failed
	...
Caused by: java.security.cert.CertificateExpiredException: NotAfter: Wed Apr 01 02:00:00 CEST 2026
```

Java 23 and later, and recent updates of Java 17 and 21, add `(certificate_expired)` in front; older versions, including Java 8 and 11, start with `PKIX path validation failed`. The date after `NotAfter:` is printed in the JVM’s local time zone. A certificate that is not valid yet gives `CertificateNotYetValidException: NotBefore: …` instead. The strings come from OpenJDK’s [BasicChecker.java](https://github.com/openjdk/jdk/blob/master/src/java.base/share/classes/sun/security/provider/certpath/BasicChecker.java) and [CertificateValidity.java](https://github.com/openjdk/jdk/blob/master/src/java.base/share/classes/sun/security/x509/CertificateValidity.java).

## What it means

Note the word **validation**. “PKIX path *building* failed” means Java found no path to a trusted root at all ([that page](https://pkizerotohero.com/errors/java-pkix-path-building-failed/)). “Path *validation* failed” means Java did find a path, then one of its checks failed: here the check of the [validity period](https://pkizerotohero.com/handbook/glossary/#validity-period). A certificate on the path, almost always the server’s own, is past its `notAfter` date by the JVM’s clock. Java will not use it, even though everything else is correct.

## Likely causes

### The server’s certificate expired

**Confirm** with keytool, which prints the certificates a server sends without needing to trust them:

```bash
keytool -printcert -sslserver api.example.com:443
```

```text
Certificate #0
====================================
Owner: CN=api.example.com
Issuer: CN=Example Issuing CA, O=Example CA
Serial number: 1000
Valid from: Thu Jan 01 00:00:00 UTC 2026 until: Wed Apr 01 00:00:00 UTC 2026
```

**Fix:** renew the certificate, install it with its full chain, and reload the server. If it is not your server, tell its owner. Public TLS certificates may be valid for at most 200 days since 15 March 2026, and for at most 47 days from 15 March 2029, so automate renewal and monitor expiry: [How to check when a certificate expires, and monitor it](https://pkizerotohero.com/guides/check-certificate-expiry/).

### It was renewed, but a Java server still uses the old keystore

Tomcat, Jetty, Spring Boot and other Java servers read their keystore when the connector starts. A new certificate in the file does nothing until the connector reloads. **Confirm** what the keystore holds, and compare it with what `keytool -printcert -sslserver` shows:

```bash
keytool -list -v -keystore server.p12 -storepass changeit | grep -E 'Alias name|Valid from'
```

**Fix:** restart the server, or use its reload feature, and test again. Behind a load balancer, test each node. See [How to install a certificate in Tomcat and other Java servers](https://pkizerotohero.com/guides/install-certificate-tomcat/).

### An intermediate in the chain expired

If `Certificate #1` or higher in the `keytool -printcert -sslserver` output is out of date, the server sends an old intermediate. Rebuild the chain from the CA’s current intermediate and reload. See [How to build the full chain file your server needs](https://pkizerotohero.com/guides/build-fullchain/).

### The JVM’s clock is wrong

If the dates look fine but one machine or container fails, check its time in UTC (`date -u`), and the time zone the JVM uses. Turn on time synchronisation (`sudo timedatectl set-ntp true` on systemd Linux, `w32tm /resync` on Windows). A clock that runs far enough behind gives `CertificateNotYetValidException`, with `(bad_certificate)` in front on versions that show the alert name.

### A client certificate expired

In [mutual TLS](https://pkizerotohero.com/handbook/glossary/#mutual-tls), a server also checks the client’s certificate. If a Java **server’s** log shows this exception during a client’s handshake, look at the client certificate’s dates and issue the client a new one.

Warning

Do not switch off the check

A `TrustManager` that accepts everything, or an “insecure” option in a framework, hides this error by accepting every certificate, including an attacker’s. The expired certificate is still expired. Renew it, or correct the clock.

## Check yours

*Interactive tool: Certificate decoder (runs in the browser at [/tools/decoder/](https://pkizerotohero.com/tools/decoder/))*

Paste the server’s certificate (PEM, for example from `openssl s_client -showcerts`). The decoder shows `notBefore`, `notAfter` and how many days are left or overdue.

## Learn why

- [Anatomy of an X.509 certificate](https://pkizerotohero.com/handbook/x509-certificates/): the validity fields.
- [Inventory, expiry and renewal](https://pkizerotohero.com/handbook/certificate-lifecycle/): stopping expiry outages.
- Related: [PKIX path building failed](https://pkizerotohero.com/errors/java-pkix-path-building-failed/) and [verify error:num=10](https://pkizerotohero.com/errors/openssl-certificate-has-expired/).

**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-certificate-expired/).

Last reviewed 20 October 2026Edition 0.9

## Learn why it happens

- [Chapter 8: Anatomy of an X.509 certificate](https://pkizerotohero.com/handbook/x509-certificates/)
- [Chapter 19: Inventory, expiry and renewal](https://pkizerotohero.com/handbook/certificate-lifecycle/)

## Fix it step by step

- [How to check when a certificate expires, and monitor it](https://pkizerotohero.com/guides/check-certificate-expiry/)
- [How to add a CA to a Java trust store (cacerts)](https://pkizerotohero.com/guides/add-root-ca-java/)

## Everything on this topic

- [Lifecycle and automation](https://pkizerotohero.com/topics/lifecycle-and-automation/)
