Cloudflare SSL Modes: Flexible, Full, and Full (Strict)
The orange cloud terminates HTTPS at Cloudflare’s edge. The SSL/TLS encryption mode is a separate choice: how Cloudflare talks to your server. Flexible makes the browser padlock appear while the origin still receives plain HTTP. That is the usual cause of ERR_TOO_MANY_REDIRECTS on an otherwise “HTTPS” Cloudflare site.
Key takeaways
- Full (strict) is the mode to use. Cloudflare connects to the origin over HTTPS and checks that the origin certificate is valid for that hostname.
- Flexible encrypts only the visitor → Cloudflare leg. The origin sees HTTP, so an HTTP→HTTPS redirect on the server loops.
- Full (without strict) encrypts the origin leg but accepts a self-signed or mismatched certificate. Fine as a temporary step, not the end state.
- Grey-cloud (DNS only) skips these modes. The browser talks to the origin directly, so the origin certificate is what visitors see.
What each mode actually does
There are two connections. Visitors always hit Cloudflare. Cloudflare then opens a second connection to the origin IP on the A/AAAA record. The mode only changes that second hop.
- Off. No encryption on either hop. Browsers mark the site Not Secure. Do not use this.
- Flexible. Browser → Cloudflare is HTTPS. Cloudflare → origin is HTTP on port 80. The origin has no certificate involved. Apps that build URLs from the incoming scheme emit
http://links, which is how mixed content shows up behind a padlock. - Full. Both hops are HTTPS. Cloudflare does not validate the origin certificate, so an expired or self-signed cert on the server still “works” for visitors. Anyone who can answer on the origin IP can present anything.
- Full (strict). Both hops are HTTPS, and the origin certificate must be unexpired and match the hostname Cloudflare connects to. A public CA certificate (Let’s Encrypt) or a Cloudflare Origin CA certificate both qualify. Origin CA certs are trusted by Cloudflare only — browsers never see them, because they talk to the edge certificate.
Why Flexible causes a redirect loop
The origin thinks every request is HTTP, because that is how Flexible delivers it. If the server (or WordPress, or an application) answers with a 301 to https://, Cloudflare follows that redirect by connecting to the origin over HTTP again. The origin redirects again. The browser reports too many redirects. “Always Use HTTPS” at the edge does not break the cycle while the origin keeps sending the same 301.
The same mismatch produces mixed content: the HTML is served as HTTPS from the edge, while the origin prints asset URLs with the scheme it saw, which was HTTP. See how to fix a redirect loop for the www / non-www variant, which is a separate loop and can stack on top of this one.
Switch to Full (strict)
- Put a certificate on the origin before you change the mode. Either run Certbot (our Nginx + Certbot guide) or, in Cloudflare, open SSL/TLS → Origin Server → Create Certificate and install that certificate and key on the origin. The certificate’s names must include the hostname Cloudflare uses to connect — usually
example.comand*.example.comif you proxy subdomains. - Confirm the origin answers HTTPS on port 443 for the real hostname, not the bare IP (the certificate name will not match an IP). With the DNS record grey-clouded, or from a host that can reach the origin directly,
curl -vI https://example.comshould finish the handshake without a certificate error. Connection refused means Full (strict) will return 525. - In the dashboard set SSL/TLS → Overview to Full (strict). Leave SSL/TLS → Edge Certificates → Always Use HTTPS on, so port 80 at the edge 301s to HTTPS. With strict mode, Cloudflare already reaches the origin over HTTPS, so the origin’s own HTTP→HTTPS redirect no longer fires on proxied traffic.
- If a loop remains, the origin is still redirecting HTTPS to HTTPS (www vs apex, or a trailing slash rule that points at itself). Pick one canonical host and redirect only the other name. Details are in the HTTP to HTTPS redirect guide.
Full without strict is a reasonable halfway step when the origin cert is self-signed and you cannot install a real one in the same change. Do not leave it there: Cloudflare will not notice when that certificate expires or is replaced by an attacker’s.
How to verify
After the change, purge the Cloudflare cache and load the site in a private window. http:// should 301 once to https:// and stop. Run the domain through the HTTPS checker: the redirect chain should be a single hop, the certificate should be valid for the hostname, and mixed content should be gone. Cloudflare 525 means the origin did not complete a TLS handshake on 443. 526 means it did, but Full (strict) rejected the certificate (expired, self-signed, or wrong name). Fix the origin certificate — do not switch back to Flexible.
Certificate errors on the edge certificate itself (expired, wrong name) are a different problem. Use how to fix SSL certificate errors.