错误信息
curl: (60) SSL certificate problem: certificate has expired
也可能输出为
- curl: (60) SSL certificate OpenSSL verify result: certificate has expired (10)
在基于 OpenSSL 1.1.1、3.0 和 3.5 构建的 curl 中,原因文本完全相同。较新的 curl 版本(我们测试的是 8.22.0)会写作“SSL certificate OpenSSL verify result: certificate has expired (10)”。尚未生效的证书会给出另一个原因:“certificate is not yet valid”。
curl (OpenSSL backend) — CURLE_PEER_FAILED_VERIFICATION, X509_V_ERR_CERT_HAS_EXPIRED (10)
含义
curl 构建的证书链中,有一张证书的 notAfter 日期早于运行 curl 的机器上的当前时间。通常是服务器自己的证书,但过期的中间证书或交叉签名的根证书也会产生同样的文本。检查依据的是本地时钟,因此时钟错误看起来与证书过期完全一样。
原因
自动续期停止工作
常见从未启用的 certbot 定时器、如今在 CDN 或防火墙后面失败的 ACME 挑战、已过期的 DNS API 令牌,或者无人负责的手动流程。公共证书有效期正在缩短:2026年缩短至 200 天,2029年将缩短至 47 天,因此悄无声息的续期失败会很快暴露出来。
证书已续期,但服务器仍在提供旧证书
常见nginx、HAProxy、Postfix 和 Java 服务器在启动时加载证书。磁盘上的文件续期后,在进程重新加载之前不会有任何变化;负载均衡器和 CDN 则保留着各自上传的副本。
服务器发送的证书链中有中间证书或交叉签名证书已过期
偶见如果服务器捆绑了旧的中间证书(例如从过时的 fullchain 中复制来的交叉签名证书),即使叶子证书仍然有效,客户端也可能构建出一条经过已过期证书的路径。2021年,DST Root CA X3 根证书的交叉签名过期,许多旧客户端就是这样出问题的。
客户端时钟不准确
偶见没有电池供电时钟的设备、从快照恢复的虚拟机,以及运行在时钟漂移主机上的容器,时间可能相差几个月。如果所有 HTTPS 网站同时失败,首先检查日期。
旧客户端构建的路径指向已过期的根证书
罕见CA 证书包过时的客户端可能只认识某个根证书的过期版本,因而验证失败,尽管现代客户端会选择较新的路径。更新 ca-certificates 即可修复。
修复方法
- 1.
找出过期的证书
打印服务器发送的每张证书的 notAfter 日期。如果叶子证书已过期,就续期;如果是中间证书过期,就用 CA 当前发布的证书链文件替换现有的证书链文件。
bash # Split the served chain into cert1.pem (leaf), cert2.pem, ... and print each expiry date openssl s_client -connect api.example.com:443 -servername api.example.com -showcerts </dev/null 2>/dev/null \ | awk '/BEGIN CERT/{n++; f="cert" n ".pem"} /BEGIN CERT/,/END CERT/{print > f}' for f in cert*.pem; do openssl x509 -in "$f" -noout -subject -enddate; done - 2.
续期、重新加载,并检查实际提供的证书
续期后,重新加载为该主机名终止 TLS 的所有进程和设备,然后从网络侧确认日期,而不是查看磁盘上的文件。
bash sudo certbot renew # or your ACME client / CA portal sudo systemctl reload nginx # the server keeps serving the old file until reloaded echo | openssl s_client -connect api.example.com:443 -servername api.example.com 2>/dev/null \ | openssl x509 -noout -enddate # confirm the new date is what the network sees - 3.
校正客户端时钟
如果证书在其他机器上没有问题,就用 NTP 同步出错机器的时间。容器的时钟来自宿主机,因此要在宿主机上修复。
bash date -u # compare with the real UTC time timedatectl status # "System clock synchronized: yes"? sudo timedatectl set-ntp true - 4.
更新客户端的 CA 证书包
在长期运行的系统上,更新后的 ca-certificates 软件包会移除已退役的根证书并加入当前的根证书,让 OpenSSL 能够选择有效的路径,而不是已过期的路径。
bash # Old clients: refresh the root store so they stop building paths through retired roots sudo apt-get update && sudo apt-get install --only-upgrade ca-certificates # Debian/Ubuntu sudo dnf upgrade ca-certificates # RHEL/Fedora
相关错误
verify error:num=10:certificate has expiredOpenSSL CLI (openssl s_client / openssl verify)x509: certificate has expired or is not yet valid: current time 2026-08-20T15:4…Go crypto/x509certificate has expiredNode.js tls / https / fetch[SSL: CERTIFICATE_VERIFY_FAILED] certificate verify failed: certificate has exp…Python ssl module (OpenSSL)curl: (60) SSL certificate problem: unable to get local issuer certificatecurl (OpenSSL backend)