# Composer "SSL operation failed with code 1": how to fix it

> Composer's "SSL operation failed" or curl error 60 means PHP could not verify Packagist's certificate. Fix PHP's CA bundle; never set disable-tls.

Source: https://ssl.sh/errors/composer-ssl-operation-failed/
Last updated: 2026-11-10

**Composer's `SSL operation failed with code 1 ... certificate verify failed` means PHP connected to Packagist (or your private repository) but could not verify its certificate.** Usually PHP has no usable CA bundle configured, an antivirus or proxy is intercepting HTTPS, or a private repository uses a CA that PHP does not trust.

## Quick fix

A missing or outdated CA file in the `composer diagnose` output is the usual cause.

Let Composer show you what it checks:

```bash
composer diagnose -vvv
php -r 'print_r(openssl_get_cert_locations());'
php --ini
```

If the CA file Composer reports is missing or outdated, set a valid bundle in the php.ini used by the CLI:

```ini
openssl.cafile = "/etc/ssl/certs/ca-certificates.crt"
curl.cainfo = "/etc/ssl/certs/ca-certificates.crt"
```

On Windows, download `cacert.pem` from curl.se, save it next to PHP, and use that path. Run `composer diagnose` again; the HTTPS checks should now pass.

## Causes

### 1. PHP has no usable CA bundle

Windows PHP builds, XAMPP and custom builds often have empty `openssl.cafile` and `curl.cainfo` settings and no default CA file.

- **Confirm:** `openssl_get_cert_locations()` points to a path that does not exist.
- **Fix:** set both directives in the CLI php.ini (`php --ini` shows which one). Composer runs on the CLI, so the web server's php.ini does not matter here.

### 2. Antivirus or proxy HTTPS scanning

The Composer troubleshooting guide names Avast's HTTPS scanning on Windows as one example (see [antivirus HTTPS scanning](https://ssl.sh/errors/antivirus-https-scanning-ssl-error/)); corporate TLS-inspecting proxies behave the same way.

- **Confirm:** `composer diagnose` finds a valid CA file but still fails, and the error disappears when HTTPS scanning is turned off or on another network.
- **Fix:** exclude PHP or Composer from HTTPS scanning, or add the proxy's root to the bundle you point PHP at. Report the issue to the security vendor.

### 3. Outdated CA bundle or old Composer

An old `cacert.pem`, an unpatched OS or an old Composer release may lack current roots.

- **Fix:** update the OS `ca-certificates` package, download a fresh `cacert.pem`, and run `composer self-update` (with a working CA setup).

### 4. A private repository with an internal CA

Satis, GitLab, Nexus or Artifactory repositories often use internal certificates.

- **Confirm:** the failing URL is your internal host, while packagist.org works.
- **Fix:** add the internal root to the bundle, or set it for Composer only:

```bash
composer config --global cafile /etc/ssl/certs/company-bundle.pem
```

If the server is missing its intermediate certificate, fix it on the server; check it with the [SSL checker](https://ssl.sh/tools/ssl-checker/).

### 5. A wrong system clock

A clock far in the past or future makes valid certificates look expired. Enable time synchronisation.

## Fixes by environment

Every fix points PHP at a current CA bundle that also holds any private or proxy roots; the same bundle fixes [curl error 60](https://ssl.sh/errors/curl-60-ssl-certificate-problem/) in other tools.

**Debian / Ubuntu:** `sudo apt-get install --reinstall ca-certificates`, then make sure `/etc/php/<version>/cli/php.ini` does not point to a stale custom bundle.

**RHEL family:** use `/etc/pki/tls/certs/ca-bundle.crt`; add private roots with `update-ca-trust`.

**Windows / XAMPP / Laragon:** set `openssl.cafile` and `curl.cainfo` to a downloaded `cacert.pem` in the php.ini that `php --ini` reports, and make sure `extension=openssl` is enabled.

**Docker:** install `ca-certificates` in the image and copy private roots in before `composer install`. In CI, run `composer diagnose` as a first step when installs fail.

**Same problem in your application code:** see [PHP cURL error 60](https://ssl.sh/errors/php-curl-error-60/).

## Don't do this

- **`composer config -g disable-tls true`.** Composer's documentation calls this a security risk; every download falls back to plain HTTP.
- **`composer config -g secure-http false`** to use an `http://` mirror. It allows unauthenticated downloads of code you will execute.
- **Turning off `verify_peer` in a custom stream context** or in Composer plugins. It disables the check that protects you from tampered packages.
- **Downloading `cacert.pem` from an unofficial source.** Use the file from curl.se or your OS package.
