Problem entry · machine-readable · 编码代理与终端

pip install 报 SSL 证书错误(CERTIFICATE_VERIFY_FAILED)——信任链断了,别急着 --trusted-host

本页嵌入 #trove-entity JSON(本条目全量结构化数据);全库数据见 /agent/trove.json。

元数据

idpip-ssl-cert收录2026-09-01
问题域编码代理与终端主题分组网络与镜像
适用工具pip · 外部工具

症状

`pip install` 报 `SSLError(SSLCertVerificationError: [SSL: CERTIFICATE_VERIFY_FAILED] certificate verify failed: self-signed certificate)` 或 `unable to get local issuer certificate` / `certificate has expired`;浏览器能打开包源、curl 正常,唯独 pip 失败;换源后错误不变。

原因

HTTPS 的证书校验链路是「客户端信任库 → 服务器证书 → 逐级验签直到根证书」:pip 用自己捆绑的 CA 包(certifi),与浏览器/系统信任库是**三套独立列表**——这就是「浏览器能开、curl 能下、pip 报错」的机制解释。校验有三个独立条件:①链上每张证书都在信任库可追溯(自签证书在链顶端直接断裂 → `self-signed certificate`);②证书未过期且系统时间正确(→ `certificate has expired`);③主机名与证书 SAN 匹配。公司代理 MITM 时,代理对每个站点签发的都是「代理自己的证书」,所以**换源必然无效**——证书不是源的,是代理的。确定性判断路径:`openssl s_client -connect <host>:443 -showcerts` 看 `subject=`/`issuer=` 是否相同(自签)或 issuer 是否为内部 CA(MITM);`--trusted-host` 是把「校验」整段短路,不是修复,装包前想清楚这一点。

pip 的 HTTPS 证书链校验失败:服务器证书不是由 pip 信任库(certifi)里任何 CA 签发。三种来源:自签证书(内网镜像/私有仓库)、公司 SSL 拦截代理的私有 CA(换源无效)、证书过期/系统时间错。`--trusted-host` 是跳过校验不是修复。

解法

1. **正规修复**:CA 证书导入系统信任库(`/usr/local/share/ca-certificates/` + `update-ca-certificates`),再让 pip 指向系统 bundle(`pip config set global.cert /etc/ssl/certs/ca-certificates.crt`)——实测 SSL 阶段通过。

2. **临时绕过**:`pip install --trusted-host <域名> ...`,仅救急,长期等于关掉 HTTPS 身份校验。

3. **场景分流**:内网镜像找管理员要 CA;公司代理找 IT 要拦截证书(换源无用);`expired` 先校时。

4. **Python 3.14 注意**:源地址用域名不用 IP 字面量(实测会触发 `check_hostname requires server_hostname`)。

验证证据

- 2026-09-01 本机实测(WSL Ubuntu 26.04,Python 3.14.4,pip 25.1.1,自建 127.0.0.1:18443 HTTPS 源 + 自签 CA,SAN=DNS:localhost,IP:127.0.0.1):`实测复现日志(2026-09-01)`

- 基线:`pip install --index-url https://localhost:18443/simple/ six` → `[SSL: CERTIFICATE_VERIFY_FAILED] certificate verify failed: self-signed certificate (_ssl.c:1081)`(实锤);

- 快速绕过:`--trusted-host localhost` → SSL 阶段放行,后续报 `No matching distribution`(实锤:跳过校验生效);

- 正规修复:CA 复制进 `/usr/local/share/ca-certificates/` + `update-ca-certificates` + `pip --cert /etc/ssl/certs/ca-certificates.crt` → SSL 阶段放行(实锤);

- 负对照:撤销 CA + 不带 `--cert` → 回到 `CERTIFICATE_VERIFY_FAILED: self-signed certificate`(实锤:修复确实依赖信任库,不是缓存);

- 变体:`https://127.0.0.1:18443`(IP 字面量)→ `ValueError: check_hostname requires server_hostname`(Python 3.14 新行为,实锤)。

来源与证据

素材来源:本站实测沉淀(2026-09-01)

验证证据:Evidence details kept locally (2026-09-01)