composer报“signature has expired”错误主因是系统时间偏差超±900秒,需校准时间;其次可临时设composer_disable_signatures=1绕过,或升级composer并清缓存。

Composer install/update 报错 “Signature has expired”
这是 Composer 从 2.5.0 开始启用的「签名验证机制」触发的典型失败,不是网络或权限问题,而是本地时间与 Packagist 服务器时间偏差过大(通常 > 15 分钟),导致 JWT 签名中的 exp(过期时间)字段被判定为已失效。
检查并校准系统时间(最常见原因)
Packagist 的签名证书依赖严格的时间同步。Linux/macOS 下运行 date 查看当前时间,Windows 下用 time /t 或任务管理器 → 性能 → 时间。偏差超过 ±900 秒就会触发该错误。
- Linux/macOS:执行
sudo ntpdate -s time.apple.com(macOS)或sudo timedatectl set-ntp true(systemd 系统) - Windows:右键任务栏时间 → 「调整日期/时间」→ 开启「自动设置时间」和「自动设置时区」
- WSL 用户注意:WSL 默认不继承 Windows 时间,需在 WSL 内运行
sudo hwclock -s或定期同步
临时禁用签名验证(仅限调试/离线环境)
不推荐长期使用,但可快速验证是否为签名机制本身导致失败。该操作跳过所有包的签名检查,包括 vendor/ 中已安装包的完整性校验。
- 全局关闭:运行
composer config -g security.disable-tls true(⚠️ 实际上是禁用 TLS 验证,非签名)→ 错误做法 - 正确方式:运行
composer config -g secure-http false并配合composer config -g disable-tls true(仍不解决签名) - 真正绕过签名:设置环境变量
COMPOSER_DISABLE_SIGNATURES=1,再执行composer install - Docker 中添加:
ENV COMPOSER_DISABLE_SIGNATURES=1到 Dockerfile
升级 Composer 并清理缓存(旧版本兼容性问题)
Composer 2.4.x 及更早版本未实现完整的签名验证逻辑,遇到新签名格式会直接报错;而 2.5.0+ 版本对时间容错更敏感,但修复了签名解析 bug。同时,损坏的 repo.packagist.org 缓存可能保留过期签名元数据。
- 升级:运行
composer self-update(确保 ≥ 2.5.0) - 清缓存:运行
composer clear-cache(会删除~/.composer/cache/下所有内容) - 验证签名服务状态:访问 https://www.php.cn/link/c61ab3254a8a0d55aa901aa8649460c9,确认返回 JSON 且
validTo字段未过期
时间不准是最隐蔽也最常被忽略的点——尤其在虚拟机、Docker 容器、CI runner 或休眠唤醒后的笔记本上。哪怕只差 17 分钟,Signature has expired 就会稳定复现,且不提示具体原因。










