# curl: (77) error setting certificate verify locations: fix

> curl error 77 means curl could not read its CA bundle: a missing ca-certificates package, a wrong CURL_CA_BUNDLE or --cacert path, or file permissions.

Source: https://ssl.sh/errors/curl-77-error-setting-certificate-verify-locations/
Last updated: 2026-11-10

**`curl: (77)` means curl could not open or parse the CA bundle it was configured to use, so it cannot verify any server.** The message names the exact `CAfile` and `CApath`; one of them is missing, empty, unreadable, or pointed somewhere wrong by an environment variable or option.

## Quick fix

The paths in the message show which CA file curl could not read.

Check the path from the message and what overrides it:

```bash
ls -l /etc/ssl/certs/ca-certificates.crt
env | grep -E 'CURL_CA_BUNDLE|SSL_CERT_FILE|SSL_CERT_DIR'
curl -V
```

- **File missing:** install the CA package (below).
- **Variable points to a missing file:** `unset CURL_CA_BUNDLE SSL_CERT_FILE` and remove it from your profile, CI settings or Dockerfile.
- **File exists:** check permissions and content (`head -1` should print `-----BEGIN CERTIFICATE-----`).

## Causes

### 1. The CA package is not installed

Minimal container images (Debian slim, Alpine, scratch-based images) often lack `ca-certificates`.

- **Confirm:** the path in the message does not exist.
- **Fix:**

```bash
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
```

### 2. A wrong path from an option or environment variable

`--cacert`, `--capath`, `CURL_CA_BUNDLE`, `SSL_CERT_FILE`, or a `cacert` line in `~/.curlrc` may point to a file that was moved or never existed (for example a path copied from another distribution).

- **Confirm:** the CAfile in the error differs from your distribution's default.
- **Fix:** correct or remove the setting. Distribution defaults are `/etc/ssl/certs/ca-certificates.crt` (Debian, Ubuntu, Alpine) and `/etc/pki/tls/certs/ca-bundle.crt` (RHEL family).

### 3. Permissions or SELinux

- **Confirm:** the file exists, but `sudo -u www-data cat /path/file` fails, or the audit log shows an SELinux denial.
- **Fix:** CA bundles are public data; make them world-readable (`chmod 644`) and restore labels with `restorecon`.

### 4. A curl built for another layout

A curl binary copied between systems, or a static build, has a compiled-in CA path from its build machine.

- **Confirm:** `curl -v https://example.com 2>&1 | grep CAfile` shows a path that does not exist on this system.
- **Fix:** use the distribution's curl package, or always pass `--cacert` with a valid bundle.

### 5. Empty or corrupted bundle

An interrupted update or a failed download can leave an empty file.

- **Fix:** reinstall the package or run `update-ca-certificates` (Debian/Alpine) or `update-ca-trust` (RHEL).

## Fixes by environment

Everywhere, the fix is a readable [PEM](https://ssl.sh/glossary/pem/) bundle of [root certificates](https://ssl.sh/glossary/root-certificate/) at the path curl expects. After that, a remaining trust problem appears as [curl error 60](https://ssl.sh/errors/curl-60-ssl-certificate-problem/).

**PHP:** `curl.cainfo` or `openssl.cafile` in php.ini pointing to a missing `cacert.pem` produces error 77 from PHP's cURL extension. Fix the path or remove the setting to use the system bundle; see [PHP cURL error 60](https://ssl.sh/errors/php-curl-error-60/).

**Windows:** curl.exe shipped with Windows uses the Windows store and does not need a bundle. Third-party OpenSSL builds look for `curl-ca-bundle.crt` next to the executable or use `CURL_CA_BUNDLE`; download the bundle from curl.se.

**Docker:** add `ca-certificates` in the same stage that runs curl; multi-stage builds often install it only in the builder stage.

**CI runners:** check job-level variables; a `CURL_CA_BUNDLE` meant for one job can leak into others.

**Python, Git and other tools:** many tools read `SSL_CERT_FILE` too, so a broken value can make several programs fail at once with different-looking errors. Fix the variable once rather than patching each tool.

## Don't do this

- **`curl -k` to "get past" the error.** Verification is then off for that request; fix the bundle instead.
- **Point the bundle at a single private root.** `--cacert` replaces the default list, so public sites will fail with error 60. Append private roots to the system store instead.
- **Download a random `cacert.pem`.** Use your package manager or the bundle published on curl.se.
