526: Invalid SSL certificate

What does the certificate your origin server presents look like?

Expired, or the validity dates look wrong

Cloudflare completed the TLS handshake with your origin but refused the certificate because it is outside its validity window. Under Full (Strict), an expired certificate is rejected outright rather than warned about.

Check

Read the certificate's notBefore and notAfter dates straight from the origin, bypassing Cloudflare, and compare them to the current date.

Fix

Renew the certificate and reload the web server so it serves the new one. If renewal is automated, check the renewal job actually ran and that the server was reloaded afterwards — a renewed file that the running process hasn't picked up looks identical to an expired one from Cloudflare's side.

openssl s_client -connect ORIGIN_IP:443 -servername example.com </dev/null 2>/dev/null | openssl x509 -noout -dates
sudo certbot renew && sudo systemctl reload nginx

Verify

Re-run the openssl command and confirm notAfter is in the future, then reload the site through Cloudflare and confirm the 526 is gone.

Self-signed, or issued by an internal CA

Full (Strict) requires the origin to present a certificate signed by a publicly trusted CA or by Cloudflare's Origin CA. A self-signed certificate, or one from an internal corporate CA, is rejected because Cloudflare has no way to establish a chain of trust to it.

Check

Compare the certificate's issuer to its subject. If they match, it is self-signed.

Fix

Install a Cloudflare Origin CA certificate on the origin — it is free, valid for up to 15 years, and trusted by Cloudflare specifically for this path. Generate it under SSL/TLS → Origin Server → Create Certificate in the dashboard. A publicly trusted certificate (Let's Encrypt or any commercial CA) also works if the origin is reachable for domain validation. Switching the zone to Full instead of Full (Strict) will also clear the error, but it stops Cloudflare validating the origin at all — treat that as a temporary unblock, not a fix.

openssl s_client -connect ORIGIN_IP:443 -servername example.com </dev/null 2>/dev/null | openssl x509 -noout -subject -issuer

Verify

Reload the site through Cloudflare with the zone still on Full (Strict) and confirm the 526 is gone.

Valid, but issued for a different hostname

The certificate is valid and properly signed, but the hostname Cloudflare sends in SNI isn't listed in its Subject Alternative Names. A certificate covering example.com does not cover www.example.com unless www is listed explicitly or the certificate is a wildcard.

Check

List the certificate's Subject Alternative Names and confirm the exact hostname being requested appears among them.

Fix

Reissue the certificate with every hostname Cloudflare will request listed in its SAN, or use a wildcard covering the subdomains. If the origin serves several sites, also confirm the right virtual host is selected for that SNI name — the wrong default vhost will present the wrong certificate.

openssl s_client -connect ORIGIN_IP:443 -servername www.example.com </dev/null 2>/dev/null | openssl x509 -noout -text | grep -A1 'Subject Alternative Name'

Verify

Re-run the command with the failing hostname in -servername and confirm it now appears in the SAN list.

I don't know — how do I check?

A 526 always means the same thing — Cloudflare reached your origin over TLS and then rejected its certificate — but the specific reason (expiry, trust chain, or hostname) can only be read off the certificate itself.

Check

Connect straight to the origin IP, bypassing Cloudflare, sending the same SNI hostname Cloudflare uses, and read the dates, subject, issuer and SAN list in one go.

Fix

Run the command below against your origin's real IP address. Expired dates point to a renewal that didn't complete; a subject and issuer that match mean it is self-signed; a hostname missing from the SAN list means the certificate is for a different name. An incomplete chain — the server not sending its intermediate certificate — presents the same way, so check that the chain returned is complete as well.

openssl s_client -connect ORIGIN_IP:443 -servername example.com -showcerts </dev/null 2>/dev/null | openssl x509 -noout -dates -subject -issuer
curl -vI --resolve example.com:443:ORIGIN_IP https://example.com/

Verify

Once you know which of the three applies, look up 526 again and pick that answer for the specific fix.

Want to narrow it down interactively instead? Use the error lookup tool.