跳到主要内容
ecdsa.com
Java (JSSE)Java

错误信息

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 validation”(路径验证)而不是“path building”(路径构建),这说明信任没有问题,问题出在日期上。嵌套的 CertificateExpiredException 或 CertificateNotYetValidException 会指出越过的是哪一个边界。

原因

修复方法

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

相关错误

浏览完整的签名错误库