• curl
  • Exact text checked with the real tool

curl: (77) error setting certificate verify locations

Also seen in: git, PHP, other programs built on libcurl

In one sentence

curl could not load the CA certificates it was told to use: the bundle file is missing, unreadable or not PEM. The server was never checked.

Where you see it

curl exits with code 77, CURLE_SSL_CACERT_BADFILE: “Problem with reading the SSL CA cert (path? access rights?)” (libcurl error codes). The wording depends on curl’s version and TLS library. With OpenSSL 1.1.1:

$ curl https://example.com/
curl: (77) error setting certificate verify locations:
  CAfile: /etc/ssl/certs/ca-certificates.crt
  CApath: /etc/ssl/certs

Other versions say the same thing differently (curl’s openssl.c):

  • curl with OpenSSL 3, up to curl 8.16: curl: (77) error setting certificate file: /etc/ssl/certs/ca-certificates.crt
  • curl 8.17 and later: error adding trust anchors from file: … (with OpenSSL 1.x: error adding trust anchors from locations:)
  • Git for Windows’ curl with Schannel: curl: (77) schannel: failed to open CA file 'C:/certs/ca.pem': The system cannot find the path specified.
  • git with libcurl’s generic text: fatal: unable to access 'https://git.example.com/team/app.git/': Problem with the SSL CA cert (path? access rights?)

What it means

To check a server’s certificate, curl needs a trust store: a file (a CA bundle) or a directory of root certificates in PEM format. Code 77 means curl could not load the file it was given, so it stopped before checking the server at all. The server is not the problem; the client’s configuration is.

Likely causes

The CA bundle is not installed

Minimal container images often contain curl but no CA bundle. Confirm which file curl tries to use, and whether it exists:

curl -v https://example.com/ 2>&1 | grep -E 'CAfile|CApath'
ls -l /etc/ssl/certs/ca-certificates.crt

Fix: install the bundle:

apt-get install -y ca-certificates     # Debian and Ubuntu
apk add ca-certificates                # Alpine
dnf install -y ca-certificates         # Fedora and RHEL

For containers, put the install command in the Dockerfile, so that every container built from the image has the bundle.

A setting points to the wrong file

Many settings can tell curl or programs built on libcurl which CA file to use: --cacert, the CURL_CA_BUNDLE and SSL_CERT_FILE environment variables, cacert in .curlrc, git’s http.sslCAInfo or GIT_SSL_CAINFO, and PHP’s curl.cainfo or openssl.cafile. A path that was right on another machine, or before an upgrade moved the file, gives exactly this error.

Confirm:

env | grep -E 'CURL_CA_BUNDLE|SSL_CERT_FILE|SSL_CERT_DIR|GIT_SSL_CAINFO'
git config --show-origin --get-all http.sslCAInfo
php -i | grep -E 'curl.cainfo|openssl.cafile'

Fix: correct the path or remove the setting so the default applies. If you added the setting for a company root, add that root to the system store instead: How to trust a private root CA on Linux or How to work behind a TLS-inspecting corporate proxy, safely.

A wrong --capath directory often does not give code 77: curl then finds no root and fails later with code 60, unable to get local issuer certificate.

The file cannot be read

The file exists but the user running curl may not read it, for example after a copy with the wrong permissions, or a Windows path used inside WSL. Confirm with ls -l and by reading it as that user (head -1 /path/to/ca.pem). Fix: chmod 644 /path/to/ca.pem, or use a path the process can reach.

The file is not PEM

A CA certificate saved in DER format (often .cer or .crt on Windows), a PKCS #12 file or an HTML error page saved by mistake cannot be loaded. Confirm: a PEM file starts with -----BEGIN CERTIFICATE-----, and OpenSSL can read it:

head -1 corp-root.pem
openssl x509 -in corp-root.pem -noout -subject -enddate

Fix: convert a DER file to PEM:

openssl x509 -inform DER -in corp-root.cer -out corp-root.pem

See How to convert between DER and PEM.

Check yours

Try it: Certificate decoderOpen the full tool

Runs in your browser. Nothing you paste is sent anywhere.

PEM text, several PEM blocks, or a .pem, .crt, .cer or .der file (drop it on the box). Certificates are public, so they are safe to paste.

Paste the contents of the CA file curl should load. If the decoder can read it, it is valid PEM, and you see whose root certificate it is and when it expires.

Learn why

In the gameLevel 12: Who do we trust?Registry of Roots, Keystone. In development

Early edition. Checked against the standards; an independent expert review is in progress. Found a mistake? Tell us.

Last reviewed Edition 0.9