# 526 Invalid SSL Certificate (Cloudflare)

> Cloudflare 526 means the origin certificate failed Full (strict) validation. Check expiry, hostname and chain with openssl, then fix it.

Source: https://howhttpworks.com/status-codes/526
Last reviewed: 2026-10-04

> **TL;DR:** In Full (strict) mode Cloudflare verifies the origin certificate. 526 means that check failed: it is expired, does not cover the hostname Cloudflare asked for, is not issued by a trusted CA, or the server is not sending the intermediate certificates. Check it with `openssl s_client`, then fix or install a Cloudflare Origin CA certificate.

## What it means

The handshake succeeded (otherwise you would see [525](https://howhttpworks.com/status-codes/525)), so the origin speaks TLS. Cloudflare then validated the leaf certificate against the SNI hostname it used and found a problem. The error page reads **Error 526: Invalid SSL certificate**, with `Server: cloudflare` and a `CF-RAY` header like every Cloudflare-generated error.

Full vs Full (strict):

| Check | Full | Full (strict) |
|---|---|---|
| Origin must speak TLS | Yes | Yes |
| Expiry checked | No | Yes |
| Hostname must match SAN | No | Yes |
| Must chain to a public CA or Cloudflare Origin CA | No | Yes |

## Check the certificate the way Cloudflare sees it

Use the origin IP directly with SNI set to the hostname:

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

```text
subject=CN = www.example.com
issuer=C = US, O = Let's Encrypt, CN = R11
notBefore=Aug  1 00:00:00 2026 GMT
notAfter=Oct 30 23:59:59 2026 GMT
X509v3 Subject Alternative Name:
    DNS:example.com, DNS:www.example.com
```

Verify the whole thing, including chain and hostname:

```bash
openssl s_client -connect 203.0.113.10:443 -servername www.example.com -verify_hostname www.example.com -verify_return_error </dev/null
```

Look at the last lines: `Verify return code: 0 (ok)` is what you want. Common failures:

```text
Verify return code: 10 (certificate has expired)
Verify return code: 18 (self-signed certificate)
Verify return code: 20 (unable to get local issuer certificate)   # missing intermediates
Verify return code: 62 (hostname mismatch)
```

Count the certificates in the chain: `openssl s_client ... -showcerts` should print the leaf plus intermediates, as `Certificate chain` entries `0 s:` and `1 s:`. If only entry 0 appears with a public CA issuer, the server is not sending intermediates.

## Causes, ordered by likelihood

1. **Expired certificate.** An ACME renewal job silently failing, or a Cloudflare Origin CA certificate (valid up to 15 years but chosen at issue time) that was issued with a short validity.
2. **Hostname not in SAN.** The certificate covers `example.com` but the request is for `www.example.com`, or a wildcard `*.example.com` that does not cover `a.b.example.com`. Wildcards match one label.
3. **Missing intermediate certificate.** The server sends only the leaf. Many browsers fetch missing intermediates; Cloudflare's origin validation will not. Install `fullchain.pem` instead of `cert.pem`.
4. **Self-signed or private CA certificate** while in strict mode.
5. **A different certificate served for the SNI name** than you think: the default vhost's certificate answering because the SNI-specific `server` block is not matched.
6. **Hostname mismatch from rewriting:** an Origin Rule changes the Host or SNI to a name your certificate does not cover.

## Fix it

Use the certificate chain file with nginx:

```nginx
ssl_certificate     /etc/letsencrypt/live/www.example.com/fullchain.pem;  # leaf + intermediates
ssl_certificate_key /etc/letsencrypt/live/www.example.com/privkey.pem;
```

Apache: `SSLCertificateFile` should point to the leaf and `SSLCertificateChainFile` (or the combined file in 2.4.8+) to the intermediates.

If you do not want to manage public certificates at the origin, issue a **Cloudflare Origin CA certificate** under **SSL/TLS > Origin Server**, install it on the origin and keep Full (strict). It is trusted by Cloudflare only: direct browser access to the origin IP will show a warning, which is fine, and arguably desirable.

Temporarily switching to Full gets traffic flowing, but it silently removes validation, so a later expired or impersonated origin goes unnoticed. Treat it as a short diagnostic step, not the fix. Combine strict mode with Authenticated Origin Pulls or Cloudflare Tunnel if you also need the origin to reject non-Cloudflare traffic.

## Related

- [525 SSL Handshake Failed](https://howhttpworks.com/status-codes/525): the handshake itself failed.
- [530 Origin DNS Error](https://howhttpworks.com/status-codes/530)
- [521 Web Server Is Down](https://howhttpworks.com/status-codes/521)
- [520 Web Server Returned an Unknown Error](https://howhttpworks.com/status-codes/520)
- [HTTPS and TLS](https://howhttpworks.com/guides/https-and-tls): certificates and chains.
