エラーメッセージ
PKIX path validation failed: java.security.cert.CertPathValidatorException: validity check failed
別の表記
- javax.net.ssl.SSLHandshakeException: (certificate_expired) PKIX path validation failed: java.security.cert.CertPathValidatorException: validity check failed
JDK 21 以降では TLS アラートが先頭に付き、「(certificate_expired) PKIX path validation failed: …」となります。根本原因の行は「java.security.cert.CertificateExpiredException: NotAfter: <date>」(または CertificateNotYetValidException: NotBefore: <date>)で、日付は JVM のタイムゾーンで表示されます。
Java (JSSE) — SSLHandshakeException caused by CertPathValidatorException / CertificateExpiredException
このエラーの意味
Java はトラストアンカーまでの証明書パスを構築しましたが、その検証が日付のチェックで失敗しました。JVM の現在時刻において、パス内のいずれかの証明書が有効期間の範囲外にあります。「path building」(パス構築)ではなく「Path validation」(パス検証)と表示されるのは、信頼には問題がなく、日付に問題があったことを意味します。ネストされた CertificateExpiredException または CertificateNotYetValidException が、どちらの境界に違反したかを示します。
発生する理由
サーバーの証明書(または中間証明書)の有効期限が切れた
よくある更新が行われなかったか、更新した証明書が、Java が通信するエンドポイント(多くの場合、内部のロードバランサーや、独自のキーストアを持つ Java サーバー)にデプロイされていません。
カスタムのトラストストア内の期限切れの証明書を経由してチェーンが構築された
ときどき古い中間証明書やサーバー証明書を直接ピンニングしているトラストストアは、その証明書の有効期限が切れた後も、それを基準に検証し続けます。
JVM が動作するホストの時刻がずれている
ときどきホストの時刻がずれた仮想マシンやコンテナーでは、現在有効な証明書が期限切れに見えたり、まだ有効ではないように見えたりすることがあります。
発行されたばかりの証明書と、遅れている時刻
まれ「現在」から有効な証明書は、時刻が数分遅れているクライアントでは失敗します。このため多くの CA は notBefore を少し過去にずらしていますが、プライベート CA ではそうしていないことがよくあります。
修正方法
- 1.
最も内側の原因を読む
NotAfter または NotBefore の日付から、証明書の有効期限が切れたのか、時刻がずれているのかがわかります。
text Caused by: java.security.cert.CertificateExpiredException: NotAfter: Tue Apr 01 00:00:00 UTC 2025 -> a certificate in the chain expired on that date Caused by: java.security.cert.CertificateNotYetValidException: NotBefore: ... -> not valid yet: check the clock of this machine - 2.
サーバーが送信するすべての証明書を確認する
サーバーが提供するチェーン内の各証明書の有効期限を表示し、期限切れになっているものを置き換えてください。
bash echo | openssl s_client -connect api.example.com:443 -servername api.example.com -showcerts 2>/dev/null \ | awk '/BEGIN CERT/{n++; f="c" n ".pem"} /BEGIN CERT/,/END CERT/{print > f}' for f in c*.pem; do openssl x509 -in "$f" -noout -subject -enddate; done - 3.
カスタムのトラストストアを整理する
トラストストアのエントリを有効期間とともに一覧表示し、そこにピンニングされた期限切れの証明書を削除するか置き換えてください。
bash # Expired or pinned certificates in a custom trust store keytool -list -v -keystore app-truststore.p12 -storepass changeit | grep -E 'Alias name|Valid until|Owner' keytool -delete -alias old-corp-root -keystore app-truststore.p12 -storepass changeit