Platforms and DevOps
Cloudflare Error 525: SSL handshake failed with the origin
Error 525: SSL handshake failedCloudflare Error 525 means Cloudflare reached your origin server but could not complete a TLS handshake with it. The visitor's connection to Cloudflare worked; the leg from Cloudflare to your server failed. It only happens in Full or Full (strict) mode, because only those modes connect to the origin over HTTPS.
Where the failure is
The failure is on the second of two TLS connections, between Cloudflare and your origin:
| Leg | Who controls it | Error if it breaks |
|---|---|---|
| Visitor → Cloudflare edge | Cloudflare's edge certificate | Browser errors such as ERR_SSL_VERSION_OR_CIPHER_MISMATCH |
| Cloudflare → origin | Your server's TLS configuration | 525 (handshake failed) or 526 (certificate rejected) |
Cloudflare uses different codes when the origin cannot be reached at all, for example 521 (web server is down) and 522 (connection timed out). A 525 tells you that a TCP connection was established and the TLS layer failed on top of it.
Common causes, most frequent first
1. The origin has no working TLS on port 443
The most common case: the site was set up for Flexible mode with HTTP only, and someone later switched the zone to Full. Port 443 either serves plain HTTP or has no certificate configured. Cloudflare's own list starts with "no valid SSL certificate is installed".
Confirm it by connecting straight to the origin IP, with the real hostname as SNI:
openssl s_client -connect 203.0.113.10:443 -servername example.com -brief </dev/null
wrong version number or packet length too long means port 443 is answering in plain HTTP. A connection reset or no peer certificate available means no certificate is loaded for that name.
2. No certificate for the SNI name Cloudflare sends
Cloudflare sends the visitor's hostname in the SNI extension. If your server has certificates only for other names, or the default server block is configured to reject unknown names (ssl_reject_handshake on; in Nginx), the handshake fails. Repeat the command above with each proxied hostname, including www.
3. No cipher suite in common
Cloudflare publishes the cipher suites it offers to origins. On TLS 1.3 it supports the three standard AEAD suites. On TLS 1.2 it offers ECDHE-ECDSA and ECDHE-RSA with AES-GCM, ECDHE-RSA-AES-SHA and plain RSA AES suites, but no DHE and no CHACHA20 suites. An origin hardened to "TLS 1.2 only, CHACHA20 or DHE only" has nothing to agree on. Check what the origin accepts:
openssl s_client -connect 203.0.113.10:443 -servername example.com -tls1_2 \
-cipher 'ECDHE-RSA-AES128-GCM-SHA256' -brief </dev/null
4. Port 443 filtered or reset by a firewall
A host firewall, cloud security group or intrusion-prevention system that accepts the TCP connection and then drops the TLS traffic produces 525 rather than 522. Tools such as fail2ban that ban IPs after many requests can ban Cloudflare's own ranges, which causes intermittent 525s.
5. The origin demands a client certificate
If the origin requires mutual TLS at the TLS layer (for example Apache with SSLVerifyClient require) but Authenticated Origin Pulls is not enabled on Cloudflare, Cloudflare presents no client certificate and the server aborts the handshake. Nginx behaves differently: with ssl_verify_client on; it completes the handshake and answers with an HTTP 400 error instead.
6. Intermittent failures under load
When 525s come and go, Cloudflare recommends comparing their timestamps with the origin's error log. Look for lines such as SSL_do_handshake() failed or no shared cipher in Nginx, or worker crashes and restarts in the TLS terminator.
How to fix it
Install a certificate on the origin. Any certificate makes Full mode work; Full (strict) additionally needs a publicly trusted certificate or a Cloudflare Origin CA certificate. The Cloudflare Origin CA guide covers the second option, and Let's Encrypt works too.
Nginx:
server {
listen 443 ssl;
listen [::]:443 ssl;
server_name example.com www.example.com;
ssl_certificate /etc/ssl/example.com/fullchain.pem;
ssl_certificate_key /etc/ssl/example.com/privkey.pem;
ssl_protocols TLSv1.2 TLSv1.3;
ssl_ciphers ECDHE-ECDSA-AES128-GCM-SHA256:ECDHE-RSA-AES128-GCM-SHA256:ECDHE-ECDSA-AES256-GCM-SHA384:ECDHE-RSA-AES256-GCM-SHA384;
}
Apache: enable mod_ssl, add a <VirtualHost *:443> with SSLEngine on, SSLCertificateFile and SSLCertificateKeyFile, and list every proxied name in ServerName/ServerAlias. Then run apachectl configtest.
Firewalls: allow inbound 443 from Cloudflare's published IP ranges and exclude them from automatic banning.
mTLS origins: either enable Authenticated Origin Pulls on Cloudflare or stop requiring a client certificate on the origin.
The TLS config generator produces a protocol and cipher block that overlaps with Cloudflare's list.
How to verify the fix
- From any machine, test the origin directly:
openssl s_client -connect 203.0.113.10:443 -servername example.com -briefshould print the protocol, cipher and certificate subject. - Request the site through Cloudflare:
curl -sI https://example.com/should return your normal status code with acf-rayheader and no 525. - If you plan to use Full (strict), also check the origin certificate chain and hostname so you do not trade a 525 for a 526. The SSL checker shows what the edge presents; the handshake walk-through in how the TLS handshake works explains each step that can fail.
FAQ
Can I fix Error 525 by switching Cloudflare to Flexible?
It makes the error disappear because Cloudflare then talks to the origin over plain HTTP, but traffic between Cloudflare and your server is no longer encrypted, and an origin that redirects HTTP to HTTPS will loop with ERR_TOO_MANY_REDIRECTS. Use it only as a short stopgap while you install a certificate on the origin.
What is the difference between Error 525 and Error 526?
With 525 the TLS handshake itself never completed. With 526 the handshake worked, but in Full (strict) mode Cloudflare rejected the origin's certificate as expired, self-signed, for the wrong hostname or with an incomplete chain.
Why does Error 525 happen only some of the time?
Usually because several origins sit behind the same hostname and only one is misconfigured, or because the origin resets handshakes under load or when a firewall rate-limits Cloudflare's IP ranges. Cloudflare's documentation recommends matching the 525 timestamps against the origin web server's error log.
Does the visitor need to do anything?
No. The failing connection is between Cloudflare and the website's server, so clearing the browser cache, changing browsers or switching networks does not help. Only the site owner or hosting provider can fix it.