cURL error 35或SSL connect error是TLS握手失败,需先运行composer diagnose、curl -v https://packagist.org/packages.json和openssl version确认是否为协议协商问题,再检查OpenSSL版本、CA证书路径及代理重签等底层因素。

cURL error 35 或 SSL connect error 是 TLS 握手失败,不是网络不通,也不是 Composer 配置错了——它卡在 OpenSSL 协商第一步,必须从底层协议和证书链入手。
怎么确认真是 TLS 握手失败,不是 DNS 或代理问题
别急着改配置,先跑三行命令看根源:
- 运行
composer diagnose,重点盯HTTPS connectivity行,如果标 ERROR 并带cURL error 35或SSL connect error,基本锁定 TLS 层 - 手动测底层:运行
curl -v https://packagist.org/packages.json,如果停在* TLS handshake或报SSL routines:SSL23_GET_SERVER_HELLO:tlsv1 alert protocol version,说明不是 DNS 或路由问题 - 查 OpenSSL 版本:
openssl version,输出是OpenSSL 1.0.2k(如 CentOS 7 默认)或更低,就几乎可以确定不支持 TLS 1.3,而 Packagist 已强制要求
为什么 composer config -g secure-http false 完全没用
这个命令只是让 Composer 允许降级到 HTTP 源,但 packagist.org 会 301 强制跳回 HTTPS,最终仍要走 TLS 握手——错误照旧,甚至变成 connection reset 或重定向死循环。它还带来真实风险:
- 私有仓库若配了 HTTP,依赖可能被中间人劫持
- 该设置对
cURL error 35完全无效,因为握手失败发生在协议协商层,还没到证书校验那步 - 执行后
composer install -vvv日志里依然卡在某个 HTTPS URL,毫无改善
怎么验证并修复 CA 证书路径是否生效
Composer 默认用 PHP 的 curl.cainfo 或 openssl.cafile 路径加载证书,但很多环境根本没配,或者配了但文件格式/路径不对:
- 运行
composer config -g cafile,应该返回你指定的 PEM 文件路径;若为空,说明没配对,或证书格式不对(必须是 PEM,不能是 DER) - 运行
php -r "print_r(openssl_get_cert_locations());",检查default_cert_file是否指向一个过时的cacert.pem(比如 2021 年前的版本) - 下载最新
cacert.pem(推荐从 https://www.php.cn/link/5fe4dadcdb001d8566cd20e6d8a20251),保存后在php.ini中配好:curl.cainfo = "/path/to/cacert.pem"和openssl.cafile = "/path/to/cacert.pem" - 重启 CLI 环境或 Web 服务,再跑
php -r "var_dump(openssl_get_cert_locations());"验证路径是否生效
临时绕过验证仅用于诊断,且必须立刻清理
只在确认问题是否纯属证书或协议时用,不是解决方案:
- 临时禁用:运行
COMPOSER_NO_SSL=1 composer install,若此时成功,100% 是证书链或 TLS 协议问题 - 注意:执行完必须立刻删掉该环境变量,否则后续所有命令都走明文,依赖可能被篡改
- Windows 下等价命令是
set COMPOSER_NO_SSL=1 && composer install,用完记得set COMPOSER_NO_SSL=清空
真正难处理的是企业代理重签证书、老旧 OpenSSL ABI 不兼容、或 Docker Alpine 镜像中 OpenSSL 与 PHP 扩展版本错位——这些地方证书路径对了也没用,得换基础镜像或重编译。


















