# ERR_TOO_MANY_REDIRECTS

> Two rules are sending the browser back and forth at each other, so it gives up after about twenty hops rather than looping forever.

Source: https://cwp.sg/errors/err-too-many-redirects/  
Author: Ben Johnson  
Last verified: 2026-08-02

**Also seen as:** redirect loop, The page isn't redirecting properly, too many redirects

## What it means

Your browser asked for a page, was told to go somewhere else, asked for that, and was told to go back to where it started. After roughly 20 rounds of this it stops and shows you this error.

Almost every redirect loop on shared hosting comes from **two systems both trying to enforce HTTPS or a canonical hostname, disagreeing about who won**. The classic case: a proxy in front terminates TLS and forwards the request to your server as plain HTTP; your `.htaccess` sees plain HTTP, redirects to HTTPS; the proxy receives it, terminates TLS again, forwards as HTTP again. Forever.

## Why it happens

### Cloudflare Flexible SSL plus an HTTPS redirect on the server

This is the number one cause and it is worth checking first. In Cloudflare's *Flexible* SSL mode, Cloudflare connects to your origin over plain HTTP no matter what the visitor used. Your server sees `HTTP`, redirects to `HTTPS`, and the loop is created.

The fix is to change the SSL mode, not to remove the redirect.

### Competing www and non-www rules

One rule sends `example.com` to `www.example.com`; another sends `www.example.com` back. This happens when a redirect is configured in the control panel *and* separately in `.htaccess`, or when a WordPress plugin adds one on top of an existing rule.

### WordPress site URL mismatch

If `WP_HOME` and `WP_SITEURL` disagree with the address you are actually visiting — for instance the database says `http://` but you are on `https://` — WordPress redirects you to its idea of the canonical URL on every request.

### A stale redirect cached by the browser

A `301` is a permanent redirect and browsers cache it aggressively. Once you have fixed the underlying rule, your own browser may keep looping on the cached instruction, making a fixed site look broken.

## How to fix it

### 1. Set Cloudflare SSL to Full (strict)

In the Cloudflare dashboard: **SSL/TLS → Overview → Full (strict)**. This makes Cloudflare connect to your origin over HTTPS, so your server sees HTTPS and stops redirecting.

*Full (strict)* requires a valid certificate on the origin. If your host issues free certificates — most do — you already have one. Use *Full* only as a temporary step while a certificate is being issued, and never leave it on *Flexible*: it means the connection between Cloudflare and your server is unencrypted.

### 2. Trace the loop before changing anything

Do not guess at which rule is at fault. Watch the chain:

```
curl -sIL -o /dev/null -w '%{http_code} %{url_effective}\n' https://example.com/
```

Or see every hop in order:

```
curl -sI https://example.com/ | grep -i -E '^HTTP|^location'
```

The pair of URLs that repeat are the two rules fighting. That tells you exactly where to look.

### 3. Keep exactly one canonical redirect

Pick one host and one scheme, and enforce them in a single place. A correct, non-looping `.htaccess` rule that respects a proxy:

```apache
RewriteEngine On

# Force HTTPS, honouring X-Forwarded-Proto when behind a proxy
RewriteCond %{HTTPS} !=on
RewriteCond %{HTTP:X-Forwarded-Proto} !=https
RewriteRule ^ https://%{HTTP_HOST}%{REQUEST_URI} [L,R=301]

# Force non-www
RewriteCond %{HTTP_HOST} ^www\.(.+)$ [NC]
RewriteRule ^ https://%1%{REQUEST_URI} [L,R=301]
```

The `X-Forwarded-Proto` condition is what breaks the Cloudflare loop: when a proxy has already handled TLS, the rule stops firing.

Then remove every *other* HTTPS or www redirect — from your control panel, from plugins, and from any `wp-config.php` overrides.

### 4. Fix the WordPress URLs directly

If you cannot log in to fix them through the admin, pin them in `wp-config.php`, which overrides the database:

```php
define('WP_HOME',    'https://example.com');
define('WP_SITEURL', 'https://example.com');
```

No trailing slash. Both values must match what you type in the address bar exactly, including `www` or its absence.

### 5. Test in a private window

Cached `301`s will keep showing you the loop after you have fixed it. Always confirm a fix in a fresh private window, or with `curl`, which caches nothing.

## On CWP hosting specifically

CWP issues a free SSL certificate for every account and every custom domain, so there is no reason to run Cloudflare in Flexible mode in front of us — set **Full (strict)**.

If you added an HTTPS redirect through the control panel, do not also add one in `.htaccess`. Two is exactly one too many, and it is the most common support ticket we get in this category.

---

Content Website Platform (cwp.sg) operates the free hosting it writes about; see https://cwp.sg/about/ for the methodology and the commercial disclosure.
