命令行工具
curl: (77) error setting certificate verify locations 修复
curl: (77) error setting certificate verify locations: CAfile: /etc/ssl/certs/ca-certificates.crt CApath: nonecurl: (77) 的意思是:curl 打不开或解析不了它被指定使用的 CA 证书包,因此无法验证任何服务器。 报错里写明了 CAfile 和 CApath,其中一个不存在、是空的、没有读权限,或者被环境变量、命令行选项指到了错误的位置。
快速修复
只要让 curl 指向一个存在、可读的 CA 证书包,报错就会消失。先检查报错里的路径,以及有没有东西覆盖了它:
ls -l /etc/ssl/certs/ca-certificates.crt
env | grep -E 'CURL_CA_BUNDLE|SSL_CERT_FILE|SSL_CERT_DIR'
curl -V
- 文件不存在: 安装 CA 证书包(见下文)。
- 环境变量指向不存在的文件:
unset CURL_CA_BUNDLE SSL_CERT_FILE,并从 shell 配置、CI 设置或 Dockerfile 里删掉它。 - 文件存在: 检查权限和内容,
head -1应该输出-----BEGIN CERTIFICATE-----。
原因
最常见的原因是精简镜像没装 CA 证书包,其次是选项或环境变量给了错误路径。
1. 没装 CA 证书包
精简容器镜像(Debian slim、Alpine、基于 scratch 的镜像)经常没有 ca-certificates(系统的 CA 证书包)。
- 确认: 报错里的路径不存在。
- 修复:
apt-get update && apt-get install -y ca-certificates # Debian/Ubuntu
apk add --no-cache ca-certificates # Alpine
dnf install -y ca-certificates # RHEL/Fedora/Rocky
国内构建镜像时,先把软件源换成阿里云、清华、中科大等国内镜像,再安装,速度会快很多。
2. 选项或环境变量给了错误路径
--cacert、--capath、CURL_CA_BUNDLE、SSL_CERT_FILE,或者 ~/.curlrc 里的 cacert 行,指向的文件被移走了或者不存在(比如从别的发行版文档里抄来的路径)。
- 确认: 报错里的 CAfile 和你的发行版默认路径不一样。
- 修复: 改正或删除这个设置。发行版默认路径:Debian、Ubuntu、Alpine 是
/etc/ssl/certs/ca-certificates.crt,CentOS/RHEL 系是/etc/pki/tls/certs/ca-bundle.crt。
3. 权限或 SELinux
- 确认: 文件存在,但
sudo -u www-data cat /路径/文件失败,或者审计日志里有 SELinux 拒绝记录。 - 修复: CA 证书包本来就是公开数据,设为所有人可读(
chmod 644),用restorecon恢复标签。
4. curl 是按别的系统路径编译的
从别的系统复制过来的 curl 二进制、静态编译版,内置的是编译机上的 CA 路径。
- 确认:
curl -v https://example.com 2>&1 | grep CAfile显示的路径在本机不存在。 - 修复: 用发行版自带的 curl 包,或者每次都用
--cacert指定有效的证书包。
5. 证书包是空的或损坏了
更新中断、下载失败都可能留下一个空文件。
- 修复: 重装软件包,或者执行
update-ca-certificates(Debian/Alpine)、update-ca-trust(RHEL 系)。
各环境修法
PHP、Windows、Docker 和 CI 的修法都是让证书包出现在 curl 实际查找的位置,并让运行 curl 的用户能读到。
PHP / 宝塔: php.ini 里的 curl.cainfo 或 openssl.cafile 指向不存在的 cacert.pem 时,PHP 的 cURL 扩展会报 77。在宝塔“PHP 管理 → 配置文件”里修正路径,或者删掉这两行改用系统证书包;见 PHP cURL error 60。
Windows: Windows 自带的 curl.exe 使用系统证书库,不需要证书包文件。第三方 OpenSSL 版本的 curl 会在可执行文件旁边找 curl-ca-bundle.crt,或读 CURL_CA_BUNDLE,证书包从 curl.se 下载。
Docker: ca-certificates 要装在实际运行 curl 的那个阶段;多阶段构建常常只在构建阶段装了。
CI(GitLab Runner、Jenkins、云效): 检查任务级变量,给某个任务设置的 CURL_CA_BUNDLE 可能被带到其他任务里。
不要这样做
这 3 种做法会关闭校验,或者让访问公网网站出新的错误。
常见问题
报错 77 是网站的问题吗?
不是。curl 在加载自己的信任库时就失败了,还没看到服务器证书。CA 文件修好之前,这台机器访问任何 HTTPS 地址都会同样失败。
哪些环境变量会改变 CA 路径?
curl 会读 CURL_CA_BUNDLE,基于 OpenSSL 的版本还会读 SSL_CERT_FILE 和 SSL_CERT_DIR。~/.bashrc 里残留的 export、CI 变量、Dockerfile 里指向已删除文件的设置,都是常见原因。
文件明明存在,curl 还是报错?
确认运行 curl 的用户能读这个文件(sudo -u <用户> head -1 /路径/文件),文件是 PEM 文本且不是空的;开启 SELinux 的系统还要确认标签允许调用它的服务读取。宝塔、PHP-FPM 以 www 用户运行时尤其要注意。