# Cloudflare Error 526: invalid SSL certificate on the origin

> Error 526 means Cloudflare in Full (strict) mode rejected your origin certificate: expired, self-signed, wrong hostname or incomplete chain.

Source: https://ssl.sh/errors/cloudflare-error-526-invalid-ssl-certificate/
Last updated: 2026-11-10

**Cloudflare Error 526 means Cloudflare could not validate the certificate your origin server presented.** The handshake completed, but Full (strict) mode checks the origin certificate the way a browser would, and the check failed. The usual reasons are an expired or self-signed certificate, a certificate for another hostname, or a missing intermediate.

## What Full (strict) checks

According to Cloudflare's documentation, the origin certificate must meet all of these conditions:

| Check | Fails when |
|---|---|
| Not expired | `notAfter` is in the past, typically after a failed renewal |
| Not revoked | The CA revoked the certificate |
| Signed by a CA | It is self-signed (unless added to the Custom Origin Trust Store) |
| Hostname matches | The requested hostname is not in the Common Name or Subject Alternative Name |
| Complete chain | The origin sends only the leaf, not the intermediates |

Publicly trusted certificates and Cloudflare Origin CA certificates both pass the CA check. Full mode, by contrast, accepts any certificate, which is why the same origin can work in Full and fail in Full (strict).

## When 526 usually appears

The timing of the first 526 is often the quickest clue:

- **Right after switching the zone to Full (strict).** The origin certificate was never valid; Full mode did not check it. Look at causes 2 to 4.
- **On a date nobody touched anything.** The origin certificate reached its `notAfter` date. Look at cause 1.
- **After moving to a new server or hosting panel.** The new machine is serving a self-signed placeholder or a certificate without the intermediates.
- **After adding a new proxied subdomain.** The existing origin certificate does not list the new name.
- **Only on some requests.** One of several origins behind a load balancer or DNS round-robin has an outdated certificate. Test each origin IP separately.

## Common causes, most frequent first

### 1. The origin certificate expired

A renewal job stopped working months ago and nobody noticed. Let's Encrypt stopped sending expiry reminder emails on 2025-06-04, and Cloudflare does not send expiration notifications for Origin CA certificates, so the 526 is often the first alert. Confirm by connecting to the origin IP directly:

```bash
openssl s_client -connect 203.0.113.10:443 -servername example.com </dev/null 2>/dev/null \
  | openssl x509 -noout -subject -dates
```

### 2. Self-signed or private-CA certificate

Many hosting panels install a self-signed placeholder certificate on port 443. It is fine for Full mode but not for Full (strict). The `subject` and `issuer` printed by `openssl x509 -noout -subject -issuer` are identical for a self-signed certificate.

### 3. Hostname not covered

The certificate covers `example.com` but the proxied record is `www.example.com` or `api.example.com`, or the origin presents its default certificate because its SNI configuration does not know the name Cloudflare sends. List the names:

```bash
openssl s_client -connect 203.0.113.10:443 -servername www.example.com </dev/null 2>/dev/null \
  | openssl x509 -noout -ext subjectAltName
```

### 4. Missing intermediate certificate

The server is configured with `cert.pem` instead of `fullchain.pem`. Count the certificates the origin sends:

```bash
openssl s_client -connect 203.0.113.10:443 -servername example.com -showcerts </dev/null 2>/dev/null \
  | grep -c 'BEGIN CERTIFICATE'
```

One certificate from a public CA almost always means the chain is incomplete. See [missing intermediate certificate](https://ssl.sh/errors/missing-intermediate-certificate/).

### 5. Revoked certificate

This is less common; it happens after a key compromise report or a CA mass revocation. The CA's notification and the certificate's CRL entry confirm it.

## How to fix it

**Renew or replace the certificate.** On a server using Certbot:

```bash
sudo certbot renew --cert-name example.com
sudo systemctl reload nginx
```

**Serve the full chain.** In Nginx, `ssl_certificate` must point to the leaf followed by the intermediates (`fullchain.pem`). In Apache 2.4.8 and later, put the chain in the file named by `SSLCertificateFile`. In IIS, import the intermediate into the Intermediate Certification Authorities store.

**Cover every proxied hostname.** Reissue with all names, for example `certbot -d example.com -d www.example.com`, or use a wildcard from DNS validation.

**Use a Cloudflare Origin CA certificate** if visitors never reach the origin directly. It covers the apex and first-level wildcard by default and is accepted by Full (strict). The step-by-step is in the [Cloudflare origin certificate guide](https://ssl.sh/guides/cloudflare-origin-certificate/).

**Keep a self-signed certificate** only if you add it to Cloudflare's Custom Origin Trust Store.

**Automate renewal.** Certificate lifetimes for public TLS certificates were capped at 200 days on 2026-03-15 and drop to 100 days on 2027-03-15; Let's Encrypt's tlsserver profile already issues 45-day certificates. Use [automatic renewal](https://ssl.sh/guides/renew-certificates-automatically/) with a reload hook.

## How to verify the fix

1. Validate the origin the way Cloudflare does, from outside Cloudflare, by pinning the hostname to the origin IP:

   ```bash
   curl -sv --resolve example.com:443:203.0.113.10 https://example.com/ -o /dev/null 2>&1 \
     | grep -E 'expire date|subjectAltName|SSL certificate verify'
   ```

   `SSL certificate verify ok` means a public CA certificate is valid and complete. An Origin CA certificate fails this test by design because it is not publicly trusted; check its dates and names instead.
2. Load the site through Cloudflare and confirm the 526 page is gone.
3. Use the [chain builder](https://ssl.sh/tools/chain-builder/) to check chain order, and the [SSL checker](https://ssl.sh/tools/ssl-checker/) for the certificate visitors see at the edge.
