• 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.

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:

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 and 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). “Path validation failed” means Java did find a path, then one of its checks failed: here the check of the 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:

keytool -printcert -sslserver api.example.com:443
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.

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:

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.

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.

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, 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.

Check yours

Try it: Certificate decoderOpen the full tool

Runs in your browser. Nothing you paste is sent anywhere.

PEM text, several PEM blocks, or a .pem, .crt, .cer or .der file (drop it on the box). Certificates are public, so they are safe to paste.

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

In the gameLevel 8: The certificateRoyal Notary, Keystone. In development

Early edition. Checked against the standards; an independent expert review is in progress. Found a mistake? Tell us.

Last reviewed Edition 0.9