Skip to content
RU

curl: (77) Problem With the SSL CA Cert: How to Fix It

Monitor with blurred terminal output ending in a red error line, small server box beside it

What it means: curl could not read the CA bundle it was configured to use, so no HTTPS request can start.

  1. Check which CA file path the error names
  2. Fix or unset CURL_CA_BUNDLE, --cacert, curl.cainfo
  3. Make the file readable by the running user
  4. Install the ca-certificates package if missing
  5. Never switch off verification with -k

Test your URL now

Runs a full TLS check: handshake, protocol versions, certificate chain, trust and expiry.

Check your site's SSL →

What curl error 77 means

Exit code 77 is libcurl's CURLE_SSL_CACERT_BADFILE, documented as "Problem with reading the SSL CA cert (path? access rights?)". curl could not load the CA bundle it was told to use, so it stopped before it could verify any server. The failure is entirely local: the file named by --cacert, CURL_CA_BUNDLE, SSL_CERT_FILE, PHP's curl.cainfo, Git's http.sslCAInfo or the compiled-in default path is missing, unreadable, empty or not a PEM certificate file.

Depending on the curl and TLS library version the message reads either error setting certificate file: /path/ca.pem (current curl with OpenSSL) or error setting certificate verify locations: CAfile: ... CApath: ... (older builds). It is not a problem with the remote site's certificate. That case is error 60, SSL certificate problem: unable to get local issuer certificate, which you get when the bundle loads but does not contain the issuer.

Causes in curl, PHP, Git and other clients

ClientWhat you seeMost common trigger
curl CLIcurl: (77) error setting certificate file: /path--cacert, CURL_CA_BUNDLE or SSL_CERT_FILE pointing to a wrong, unreadable or empty file
PHP (cURL, Guzzle)cURL error 77: error setting certificate ...curl.cainfo in php.ini or CURLOPT_CAINFO set to a path that does not exist inside this PHP runtime or container
Git over HTTPSfatal: unable to access 'https://...': error setting certificate file: /pathhttp.sslCAInfo or GIT_SSL_CAINFO left over from an old setup
Minimal containersSame messages with the default path, e.g. /etc/ssl/certs/ca-certificates.crtCA bundle package not installed (FROM scratch, slim images built with --no-install-recommends)

In a test with curl 8.12 on OpenSSL 3.5, a nonexistent path, a file without read permission, an empty file and a non-PEM file all end in exit code 77, while a valid PEM file that simply lacks the right CA gives exit code 60.

On Debian and Ubuntu, libcurl4 only recommends ca-certificates, so apt-get install --no-install-recommends curl can produce a working curl binary with no bundle at the default path. Current Alpine base images already ship the bundle (ca-certificates-bundle).

Browsers never show this error. Chrome, Edge, Firefox and Safari use their own or the operating system's root store, so a site that opens in the browser can still fail with curl 77 on the same machine.

Behind Cloudflare, nginx or another proxy

A CDN, reverse proxy or load balancer cannot cause error 77: curl fails while loading a local file, before it talks to any server. The one proxy-related check is a TLS-inspection setup where --cacert, CURL_CA_BUNDLE or http.sslCAInfo points at the company root certificate; if that file is moved or missing on some machines, every client using the setting fails with 77.

If you own the server or container

Here "the site" is the machine or container running curl, PHP or Git.

  1. Find which file the client tries to load.
    env | grep -E 'CURL_CA_BUNDLE|SSL_CERT_FILE|SSL_CERT_DIR'
    git config --show-origin --get-all http.sslCAInfo
    php -i | grep -E 'curl.cainfo|openssl.cafile'
    curl -v https://example.com -o /dev/null 2>&1 | grep -E 'CAfile|CApath' 
    With a working default, curl -v prints lines such as CAfile: /etc/pki/tls/certs/ca-bundle.crt.
  2. Check the file itself.
    ls -l /path/to/ca.pem
    grep -c 'BEGIN CERTIFICATE' /path/to/ca.pem
    openssl x509 -in /path/to/ca.pem -noout -subject
    It must exist, be readable by the user running the client (for example www-data for PHP-FPM) and contain PEM certificates.
  3. Install or restore the system bundle.
    # Debian / Ubuntu  -> /etc/ssl/certs/ca-certificates.crt
    apt-get update && apt-get install -y ca-certificates
    # RHEL / Fedora     -> /etc/pki/tls/certs/ca-bundle.crt
    dnf install -y ca-certificates
    # Alpine
    apk add --no-cache ca-certificates
    # FROM scratch: copy the bundle from a build stage
    COPY --from=build /etc/ssl/certs/ca-certificates.crt /etc/ssl/certs/
  4. Add a private CA the supported way instead of a custom path: on Debian copy it to /usr/local/share/ca-certificates/ (with a .crt extension) and run update-ca-certificates; on RHEL copy it to /etc/pki/ca-trust/source/anchors/ and run update-ca-trust.
  5. Remove stale overrides: unset CURL_CA_BUNDLE, git config --global --unset http.sslCAInfo, or fix curl.cainfo and restart PHP-FPM.

Do not "fix" 77 with -k, CURLOPT_SSL_VERIFYPEER = false or http.sslVerify=false. That disables certificate verification for every request and leaves the real misconfiguration in place.

If you only use the failing app

If you see "cURL error 77" inside an application (a CMS plugin, a package manager, a deploy tool), the cause is on the server or computer running that application, not on the website it is calling and not in your browser.

  • On your own computer, follow the steps above: check environment variables, Git config and the CA bundle package.
  • On shared hosting, send the exact message, including the file path, to the hosting provider; only they can fix the PHP or system CA configuration.
  • Switching network, VPN, DNS or browser changes nothing, because the error happens before any connection is validated.

How to confirm the fix

curl -sS -o /dev/null -w '%{http_code}\n' https://example.com; echo "exit=$?"
GIT_CURL_VERBOSE=1 git ls-remote https://github.com/git/git.git HEAD

Exit code 0 and an HTTP status mean the bundle loads. If the next failure is error 60, the bundle works but the server's chain is incomplete or untrusted; check the server with the enterno.io SSL checker.

Related errors

CertificateExpiry, issuer, domains (SAN)
ChainIntermediate and root CA validation
TLS ProtocolTLS version and cipher suite
VulnerabilitiesHeartbleed, POODLE, weak ciphers

Why teams trust us

TLS 1.3
supported
Full
CA chain check
3,158
checks in 30 days
30/14/7
days-to-expiry alerts

How it works

1

Enter domain

2

TLS chain verified

3

Expiry date & vulnerabilities

What Does the SSL Check Cover?

SSL/TLS is the encryption protocol that protects data between the browser and server. Our tool analyzes the certificate, chain of trust, TLS version, and knownvulnerabilities.

Certificate Details

Issuer, validity period, signature algorithm, covered domains (SAN), and validation type (DV/OV/EV).

Chain of Trust

Full chain verification: from leaf certificate through intermediates to root CA.

TLS Analysis

Protocol version (TLS 1.2/1.3), cipher suites, Perfect Forward Secrecy (PFS) support.

Expiry Alerts

Set up a monitor — get Telegram and email alerts 30/14/7 days before expiration.

DV vs OV vs EV Certificates

DV (Domain Validation)
  • Confirms domain ownership only
  • Issued in minutes automatically
  • Free via Let's Encrypt
  • Suitable for most websites
  • Most common certificate type
OV / EV
  • Organization (OV) or Extended Validation (EV)
  • Issued in 1-5 business days
  • Costs $50 to $500/year
  • For finance, e-commerce, government sites
  • Increases user trust

Who uses this

DevOps

SSL certificate monitoring

Security

TLS config audit

SEO

HTTPS as ranking factor

E-commerce

customer trust

Common Mistakes

Expired certificateBrowsers block sites with expired SSL. Set up auto-renewal or monitoring.
Incomplete certificate chainWithout intermediate CA, some browsers and bots cannot verify the certificate.
Mixed content on HTTPS siteHTTP resources on an HTTPS page — the browser lock icon disappears, reducing trust.
Using TLS 1.0/1.1Legacy TLS versions have known vulnerabilities. Use TLS 1.2+ or 1.3.
Domain mismatch in certificateThe certificate must cover all site domains, including www and subdomains.

Best Practices

Set up auto-renewalLet's Encrypt + certbot with cron — certificate renews automatically every 60-90 days.
Enable HSTSStrict-Transport-Security header forces browsers to always use HTTPS.
Use TLS 1.3TLS 1.3 is faster (1-RTT handshake) and safer — legacy ciphers removed.
Monitor expiration datesCreate a monitor on Enterno.io — get notified well before expiration.
Verify chain after renewalAfter certificate renewal, confirm that intermediate certificates are installed.

Get more with a free account

SSL certificate monitoring, check history and alerts 30 days before expiry.

Sign up free

Learn more

Sources

Frequently Asked Questions

What is the difference between curl error 77 and error 60?

Error 77 means curl could not read the CA file at all. Error 60 means the file loaded but the server's certificate chain could not be verified against it.

Does curl -k fix error 77?

It hides the problem by disabling certificate verification, which exposes the connection to interception. Fix the CA path instead.

Why does Git or PHP fail while my browser works?

Browsers use their own or the operating system's trust store, while curl, PHP and Git read a PEM bundle file such as the one set by curl.cainfo or http.sslCAInfo. Error 77 is about that file on your machine, not about the site.

Why does it only fail inside Docker?

The image may lack the CA bundle (FROM scratch, or a slim image installed without recommended packages), or a mounted path from the host does not exist in the container.

How do I make curl trust a self-signed or private CA?

Pass the CA file with --cacert for a single request, or add it to the system store with update-ca-certificates or update-ca-trust so every client picks it up.

Try the live tool that powered this guide

Free plan — 10 monitors, checks every 5 min, no card required. Upgrade for 1-minute interval and multi-region monitoring.