You open your WordPress site and instead of a page you see ERR_TOO_MANY_REDIRECTS, or the browser says "This page isn't working. yoursite.nl redirected you too many times." The front end is unreachable. Sometimes wp-admin still works. Sometimes both are gone. The site is not really "down" in the infrastructure sense: PHP is running, the database is up, the server is answering. It is just telling the browser to go somewhere else, forever.

What the error actually means
Your browser followed a chain of HTTP redirect responses (status codes 301, 302, 307, 308) and hit a limit it imposes to stop infinite loops. Chrome and Firefox both cap the chain at around 20 hops. RFC 9110 Section 15.4 defines the 3xx redirection class, and every modern browser implements its own safety limit on top of it. Once that limit is hit, the browser stops and shows the error instead of looping forever.
The loop itself is almost always a configuration problem, not a bug: two places on your stack disagree about the canonical URL. One says "go to HTTPS", the other says "go back to HTTP". One says "add www", the other says "remove www". The browser just shuttles between them. Search engines do the same thing, so leaving the loop in place also stops new content from being indexed.
Common causes in order of likelihood
These are the five causes I see on WordPress sites, ranked by how often they turn out to be the real one:
- Mismatched Site Address and WordPress Address, or the wrong protocol on both. The two URLs under Settings > General diverge from the URL the site is actually served on. Very common right after a migration, a domain change, or a switch to HTTPS.
- Cloudflare SSL mode set to "Flexible" while the origin forces HTTPS. Cloudflare talks to the origin over plain HTTP, the origin redirects HTTP to HTTPS, Cloudflare receives the redirect and sends the visitor back to HTTPS, which hits Cloudflare, which again talks to the origin over HTTP. Classic loop.
- A broken
.htaccessrewrite rule. Usually added by an SSL or cache plugin that wrote rules alongside WordPress's own pretty-permalinks block, or a manual rule copied from a tutorial that does not fit this setup. FORCE_SSL_ADMINset on a site that is not actually reachable over HTTPS. The admin area forces HTTPS, the HTTPS request eventually lands back on HTTP, and the admin keeps bouncing.- Two plugins both forcing HTTPS or canonical redirects. An SEO plugin and a "Really Simple SSL"-style plugin both inject
wp_redirect()calls duringtemplate_redirect, disagreeing about the target URL. Less common than people assume, but it does happen.
If you are stuck on the login screen instead of a redirect loop on the front end, the shape of the problem is different: see the WordPress login redirect loop article for the auth-cookie variant that lives inside WordPress itself. For setting up the HTTPS redirect correctly from scratch, see how to force WordPress to HTTPS without the redirect loop. And if your site is behind Cloudflare and you are not sure the rest of the proxy configuration is right, the WordPress + Cloudflare configuration guide covers SSL mode, cache rules, and the plugin settings that interact with redirects.
Diagnose which cause is yours
Before you change anything, run these two checks. They tell you which fix to start with and save you from touching things that are not broken.
Look at the redirect chain in DevTools. Open the site in an incognito window with DevTools on the Network tab, check "Preserve log" and "Disable cache", and load the URL. You will see a sequence of 301/302 responses. Read the Location header of each. If the chain is http://yoursite.nl to https://yoursite.nl to http://yoursite.nl you have an HTTPS/HTTP conflict (causes 2, 4, or parts of 3). If the chain keeps adding or stripping www, it is almost always cause 1. If the loop starts as soon as you hit /wp-admin/, suspect cause 4.
Check the site URL from the database directly. Via phpMyAdmin in your hosting panel, or over SSH if you have it:
SELECT option_name, option_value
FROM wp_options
WHERE option_name IN ('siteurl', 'home');
If these two values do not match the real URL in the browser (including https:// and www or no www), you are looking at cause 1 even before wp-config.php or .htaccess enter the picture. The table prefix wp_ may be different on your install; substitute what your wp-config.php has.
Fix 1: correct the Site Address and WordPress Address
Open wp-config.php over SFTP or SSH and add these two lines above the /* That's all, stop editing! */ comment, with the exact URL you want the site served on:
define( 'WP_HOME', 'https://yoursite.nl' );
define( 'WP_SITEURL', 'https://yoursite.nl' );
These constants override the siteurl and home options in the database at runtime without changing the stored values, which is exactly what you want when the admin is unreachable. Do not put a trailing slash on the URL. Match http vs https and www vs non-www to whatever your HTTPS certificate actually covers.

Verification: reload the site in a fresh incognito window. In DevTools Network tab you should see a single 200 OK on the top-level document instead of a chain of 301s. If you still see redirects, record which URL they point to, undo the change, and move to Fix 2.
Fix 2: fix the Cloudflare SSL mode mismatch
Log in to Cloudflare, pick the affected site, and open SSL/TLS > Overview. If the mode is "Flexible", change it to "Full (strict)" if your origin has a valid certificate (Let's Encrypt, a commercial cert, or Cloudflare Origin CA), or to "Full" if the origin cert is self-signed.
"Flexible" means Cloudflare talks to your origin over plain HTTP, which directly creates a loop when the origin is configured to redirect HTTP to HTTPS. Cloudflare's own documentation explicitly warns about this. The fix is either to run the origin on HTTPS and switch to Full (strict), or to stop the origin from redirecting HTTP to HTTPS when it is being proxied. The first option is almost always the right one.
Verification: purge the Cloudflare cache (Caching > Configuration > Purge Everything), wait around 30 seconds for the change to propagate, then reload in incognito. The document request should be a single 200 again. If you control the origin directly and want to double-check, curl -sI https://yoursite.nl from the origin itself should return a 200 (not a 301 to itself).
Cloudflare Flexible SSL: why it loops and how to fix it permanently
Cause 2 deserves its own section because Cloudflare Flexible SSL is the single most common trigger for ERR_TOO_MANY_REDIRECTS on WordPress sites that were working fine before being placed behind Cloudflare. The pattern is specific and the fix is definitive, but only if you understand what Flexible actually does.
The mechanism
Flexible mode means Cloudflare encrypts the connection between the visitor's browser and Cloudflare's edge, but sends plain HTTP to your origin server. Your origin never sees an HTTPS request. If anything on the origin (an .htaccess rule, an nginx rewrite, a WordPress plugin, FORCE_SSL_ADMIN, or the "Always Use HTTPS" feature in Cloudflare itself) redirects HTTP to HTTPS, the redirect arrives back at Cloudflare's edge, which again contacts the origin over HTTP. The origin redirects again. The browser sees a 301 to HTTPS, gets a 301 to HTTPS, gets another 301 to HTTPS, and gives up after 20 hops.
The redirect chain in DevTools looks like this:
https://yoursite.nl → 301 Location: https://yoursite.nl → 301 Location: https://yoursite.nl → ...
Every hop appears to go to the same HTTPS URL. That is the giveaway: a loop where the Location header is identical to the request URL almost always means a proxy is downgrading the scheme between the edge and the origin.
Why Flexible exists (and when it is the wrong mode)
Flexible was designed for origins that have no TLS certificate at all and no way to install one. Shared hosting in 2014. Legacy servers behind firewalls. That use case has mostly disappeared: Let's Encrypt issues free certificates, most hosts automate renewal, and Cloudflare's own Origin CA issues free 15-year certificates specifically for the Cloudflare-to-origin leg. If your origin can run HTTPS (and in 2026, it can), Flexible is the wrong mode. Not because Flexible is broken, but because it was built for a constraint you almost certainly do not have.
Cloudflare's own troubleshooting guide for ERR_TOO_MANY_REDIRECTS lists Flexible mode as the first cause and recommends upgrading to Full.
The fix
- Install a TLS certificate on the origin if one is not already present. Let's Encrypt via Certbot, or a Cloudflare Origin CA certificate, both work.
- In the Cloudflare dashboard, open SSL/TLS > Overview and switch the mode from Flexible to Full (strict). Use "Full" only if the origin certificate is self-signed.
- If you have Cloudflare's "Always Use HTTPS" toggled on (under SSL/TLS > Edge Certificates), leave it on. This handles the browser-to-Cloudflare hop. What matters is that the Cloudflare-to-origin hop is now HTTPS too, so nothing loops.
- Remove any HTTP-to-HTTPS redirect rules on the origin that were added as workarounds. WordPress plugins like "Really Simple SSL" and manual
.htaccessrewrites are not harmful when the origin runs real HTTPS, but they are unnecessary when Cloudflare handles the edge redirect and they add a moving part that can break later.
Verification
Purge the Cloudflare cache (Caching > Configuration > Purge Everything), wait 30 seconds, and open the site in an incognito window with DevTools Network tab recording. You should see one 200 OK on the top-level document. No redirect chain at all.
From the origin server directly (over SSH):
curl -sI https://yoursite.nl
This should return a 200, not a 301 to itself. If it returns a 301, there is still a redirect rule on the origin that should be removed now that Cloudflare handles the HTTPS upgrade at the edge.
After resolving the redirect loop, check the front end for mixed content warnings. Sites that ran on Flexible for a while often have http:// URLs hardcoded in the database (image paths, stylesheet references, serialized widget data). Those will not loop, but they will break the padlock icon and trigger browser "Not Secure" warnings.
Fix 3: rebuild .htaccess
Rename the existing .htaccess in the WordPress root to .htaccess_broken and load the front end. If the site comes back immediately, the loop was in that file.
To get a clean one, log in to wp-admin (now reachable since the broken rules are gone), open Settings > Permalinks, and click Save Changes without changing anything. WordPress will write a fresh default .htaccess containing only the pretty-permalinks block. Do not paste the old file back in wholesale. Add any rules you actually need (IP allowlists, security headers, cache-control directives) one at a time, reloading the site after each one.
A broken .htaccess is also the most common cause of 404 Not Found on pages that exist in the admin. If you are seeing both symptoms on the same site, fixing .htaccess usually resolves both at once.
Verification: reload the site and walk through at least three URLs (home, a post, an archive). All three should return 200. The old .htaccess_broken file stays on the server for now so you can diff it later to learn which rule caused the problem.
Fix 4: review FORCE_SSL_ADMIN
Open wp-config.php and look for this line:
define( 'FORCE_SSL_ADMIN', true );
FORCE_SSL_ADMIN tells WordPress to force HTTPS on the admin area and login pages, which is what you want on any production site. The problem is when the site is not actually reachable over HTTPS: there is no certificate, or Cloudflare is set to Flexible (see also mixed content warnings in WordPress for the front-end padlock angle), or the load balancer terminates TLS but then talks to the origin over HTTP without setting X-Forwarded-Proto. WordPress then sees an HTTP request, tries to redirect it to HTTPS, gets handed back an HTTP request by the proxy, and the loop begins.
If the site has a working HTTPS certificate and Fix 2 is in place, leave FORCE_SSL_ADMIN enabled. If the proxy is terminating TLS and not forwarding the scheme, add this above the require_once ABSPATH . 'wp-settings.php'; line:
if ( isset( $_SERVER['HTTP_X_FORWARDED_PROTO'] ) && $_SERVER['HTTP_X_FORWARDED_PROTO'] === 'https' ) {
$_SERVER['HTTPS'] = 'on';
}
This tells WordPress to trust the proxy's X-Forwarded-Proto header so it stops trying to upgrade an already-HTTPS request. Only do this if the proxy is under your control and strips that header from client requests, otherwise it becomes a spoofable scheme.
Verification: clear cookies for the domain and visit /wp-admin/. You should land on the login form on the first request, not after a chain of redirects. The Network tab confirms: one 302 to wp-login.php, then a 200 on the login page itself.
Fix 5: disable plugins and isolate the conflict
If none of the above caused or resolved the loop, two plugins are probably fighting over the canonical URL. Rename wp-content/plugins to wp-content/plugins_off over SFTP. WordPress treats this as "no plugins installed" without losing any settings or deactivating anything permanently.
Reload the site. If it works, rename the folder back to plugins and deactivate plugins in batches via wp-admin: disable all of them, reload, then activate groups of four or five at a time until the loop returns. The last group you enabled contains the culprit. Within that group, narrow it down one by one. SEO plugins, "force HTTPS" plugins, and caching plugins are the usual suspects. Very rarely a theme does this in functions.php. In that case, switch temporarily to a default theme such as Twenty Twenty-Four and test again.
Verification: with only the offender deactivated, the site should load in one request again. Check whether the plugin has an option page where canonical or HTTPS redirects can be turned off. Many plugins have a "don't redirect, the server already handles it" toggle that was flipped on by accident.
Still stuck: how to escalate
If you have worked through all five fixes and the loop is still there, stop changing things and collect this before you contact your host or a WordPress engineer:
- The exact error string from the browser and the browser version.
- The redirect chain from DevTools, with every
Locationheader copied out in order. - Your current Cloudflare (or other proxy) SSL mode and any Page Rules or Transform Rules.
- The contents of
.htaccess(or the equivalent nginx location block if you are on nginx). - The
siteurlandhomevalues from the database query in the diagnosis section. - Whether
FORCE_SSL_ADMINis set inwp-config.php. - The active plugins and theme, and whether disabling all plugins resolved the loop.
- Any very recent changes: certificate renewal, WordPress core update, plugin install, DNS move, or migration to a new host.
This turns an "it's broken" ticket into a diagnostic conversation and cuts the time to resolution sharply. If the site is actually down and losing customers, this is where a managed WordPress host earns its keep: they can read the server logs directly and often see which redirect rule is firing within minutes.
Prevent it from happening again
Pick one place to handle the HTTPS and canonical redirect, and make it the only one. On a Cloudflare-proxied site that usually means "Full (strict)" plus an "Always Use HTTPS" page rule, with the origin and WordPress itself not forcing anything. On a direct-to-origin setup it means one rewrite in nginx or .htaccess, with plugins told to stand down. Before migrating or switching certificates, write down the four values that matter (siteurl, home, the Cloudflare SSL mode, and the presence of FORCE_SSL_ADMIN) so you know what they should be afterwards. Most of the loops I see come from a well-intentioned plugin adding a second layer of redirection to a setup that was already handling it correctly.
If you hit this alongside a fatal-error screen, the critical error on this website article covers the WordPress-side fatal-error variant, which sometimes surfaces after the same kind of plugin conflict.