Redirect Loop Fix: The Four Causes and How to Solve Each

By Ines Duarte ·

Redirect Loop: Why "Too Many Redirects" Happens and How to Fix It

You typed in a web address you've visited a hundred times, and instead of your homepage you got a wall of text: "This page isn't working. example.com redirected you too many times." Or maybe Chrome showed you the shorter, meaner version: ERR_TOO_MANY_REDIRECTS. Either way, you're looking at a redirect loop, and nothing you click seems to fix it.

Here's the good news: a redirect loop always has one of four root causes, and once you know which one you're dealing with, the fix is usually a five-minute job. The bad news is that most troubleshooting guides hand you a checklist of eight unrelated things to try, with no explanation of why any of them would work. This guide skips that: we'll walk through what's actually happening on the server (and in your browser), then match your exact symptom to its fix.

Before you start, it helps to have: access to your hosting file manager or FTP (for the WordPress and .htaccess fixes), your Cloudflare dashboard login if your site sits behind Cloudflare, and a private browsing window. You won't need all three, just whichever matches your situation.

What Causes a Redirect Loop

A redirect is an instruction that says "the page you want isn't here anymore, go to this other address instead." Your browser follows that instruction automatically, the way you'd follow a forwarding sticker on a piece of mail. A redirect loop happens when one of those stickers eventually points back to an address you already visited in the same trip. Your browser keeps following the trail until it gives up and shows you an error instead of a page.

That's the mechanism. But there are two different places where this error can show up, and they're often confused. ERR_TOO_MANY_REDIRECTS is what your own browser reports when it gives up following the loop, usually after somewhere around 20 hops (a figure widely cited in browser troubleshooting guides, though no Chromium spec page states it as a guaranteed number).

Google Search Console reports something different: a "redirect error" in its coverage report, which is Googlebot hitting the same loop while it crawls your site. Same problem, two different observers. If your site looks fine to you but Search Console flags a redirect error, check whether Googlebot is being treated differently than a regular visitor (more on that in the plugin section below).

The four shapes a redirect loop takes

Every redirect loop I've untangled on a client site fits into one of these four buckets. Find yours before you touch any settings.

  • A URL-mismatch loop. Two systems disagree about your site's real address: WordPress thinks it's http, your server thinks it's https, or one setting says "www" while another says "non-www." Each keeps redirecting to satisfy its own idea of the correct address, and neither wins.
  • A CDN-versus-origin SSL loop. A content delivery network like Cloudflare sits in front of your actual server. If the CDN and the server disagree about whether the connection between them should be encrypted, they can end up redirecting each other back and forth forever.
  • A browser-state loop. Your browser has stored something (a cookie, or a security instruction called HSTS) that tells it to always request https, while your server, in its current state, is still sending visitors back to http. The fight happens entirely inside your browser.
  • A rule-conflict loop. Two plugins, or a plugin and a leftover rule in your site's .htaccess file, are each trying to redirect the same page and stepping on each other. Sometimes a single rule redirects a page to itself by mistake.

Ahrefs' documentation describes a redirect loop simply as a chain that gets "stuck redirecting to one of its elements," and recommends keeping any redirect chain you do need under five hops long, since anything longer usually signals a configuration problem (Ahrefs Help Center). That's a useful gut check: if you trace a chain and count more than four or five hops before it starts repeating, something is misconfigured, not just slow.

Fixing a WordPress redirect loop (WP_HOME and WP_SITEURL mismatch)

WordPress stores two addresses for your site: the "WordPress Address" and the "Site Address." When these disagree, or one gets stuck on an old domain or the wrong protocol after a migration, WordPress and your server start arguing about where the homepage lives.

  1. Log in to your WordPress dashboard and go to Settings, then General. Check that WordPress Address (URL) and Site Address (URL) both use the same protocol (http or https) and the same domain form (with or without www). Expected result: both fields match exactly except where you deliberately run WordPress from a subfolder. If they don't match, correct them and save.
  2. If the loop is so severe you can't even reach wp-admin to make that change, open your site's file manager (through your host's control panel or an FTP client) and edit wp-config.php, which sits in your site's root folder. Add these two lines above the comment that says "That's all, stop editing!":
    define('WP_HOME','https://yourdomain.com');
    define('WP_SITEURL','https://yourdomain.com');
    Replace the address with your actual domain and save the file. Expected result: the dashboard becomes reachable again, because these constants override the database values without changing them, as documented in the WordPress Developer Handbook.
  3. Once you're back in wp-admin, go to Settings, General again, and fix the underlying values properly so they match what you hardcoded. Expected result: the General settings page saves without reverting.
  4. Remove the two lines you added to wp-config.php in step 2. Expected result: the site still loads correctly, now reading its address from the properly corrected database values instead of the temporary override. If removing those lines brings the loop straight back, the database values weren't fixed in step 3.

Fixing a redirect loop behind Cloudflare

If your site sits behind Cloudflare (or a similar proxy service), the loop can be happening between Cloudflare's edge servers and your hosting server, separate from anything WordPress is doing. This comes down to a setting called the SSL/TLS encryption mode.

In "Flexible" mode, Cloudflare talks to visitors over https but connects to your actual server over plain http. If your server has its own rule that immediately redirects every http request to https, you get a loop: Cloudflare hands it http, your server insists on https, forever.

  1. Log in to your Cloudflare dashboard, select your domain, and go to the SSL/TLS section. Expected result: you can see one of Off, Flexible, Full, or Full (strict) highlighted.
  2. If the mode is set to Flexible and your own server is also redirecting all http traffic to https (a common setting from an SSL plugin or a server-level rule), you've found the loop. Expected result: confirming this match is enough to know the fix.
  3. Change the mode to Full, or Full (strict) if your hosting has a valid SSL certificate installed on the origin server (most hosts provide one automatically through Let's Encrypt). Expected result: the site loads without looping, because Cloudflare now talks to your server over https as well, matching your server's expectation.
  4. If you can't install a certificate on the origin for some reason, the alternative fix is to remove your server's own http-to-https redirect and let Cloudflare handle the upgrade instead. Expected result: the loop stops because only one side is now doing the redirecting.

This exact mechanism, Flexible mode meeting an origin server that also redirects, is documented by Cloudflare as the standard cause of ERR_TOO_MANY_REDIRECTS on their platform, along with both fix paths above (Cloudflare Developer Docs). If you're on Apache and want the exact .htaccess rule to pair with the Full (strict) setting, htaccess.tools has a deeper walkthrough on forcing HTTPS behind Cloudflare.

When it's cookies or HSTS, not the server at all

Here's the tell that points straight at this bucket: the site works fine in a private or incognito window, but loops in your regular browser. That split is close to a diagnosis by itself: the problem is something your browser remembers about your server from a previous visit.

  1. Open a private or incognito window and load the site. Expected result: if it loads normally here, the loop is happening inside your regular browser's stored state. If it still loops in private mode too, skip this section; the problem is server-side (revisit the WordPress or Cloudflare sections above).
  2. Back in your regular browser, clear cookies for just that domain (most browsers let you do this from the site information panel next to the address bar, rather than clearing everything). Expected result: reload the site. If it now works, an old cookie, often from an SSL plugin's previous state, was the culprit.
  3. If clearing cookies didn't fix it, the likely cause is HSTS (HTTP Strict Transport Security), a setting your browser remembers separately from cookies. Once a site tells your browser "always use https for me," your browser will keep insisting on https even if the server is currently, temporarily, redirecting back to http. In Chrome, go to chrome://net-internals/#hsts, scroll to the "Delete domain security policies" box, type your domain, and click Delete. Expected result: reload the site again. It should now load without your browser forcing an upgrade the server isn't ready for.

This distinction is the single most repeated point of confusion in troubleshooting forums: people clear cookies, it doesn't help, and they assume the fix failed rather than realizing HSTS is a separate storage mechanism. The underlying collision, a browser's mandatory HTTPS upgrade meeting a server that's still redirecting back to HTTP, is documented as a genuine browser-engine edge case in a long-standing Mozilla bug report (Mozilla Bugzilla #1171203).

Plugin and .htaccess conflicts

If none of the above fits, and you're on WordPress, the remaining suspect is a rule conflict: two plugins each trying to control redirects, or a stray rule sitting in your .htaccess file (the configuration file Apache servers read on every request) that's sending a page back to itself.

  1. Through your host's file manager or FTP, find the plugins folder inside wp-content and rename it to something like plugins-disabled. Expected result: this deactivates every plugin at once without deleting anything. Reload your site. If the loop stops, a plugin was the cause.
  2. Rename the folder back to plugins, then go to your Plugins page in wp-admin (now reachable) and reactivate them one at a time, checking the site after each one. Expected result: the loop reappears the moment you reactivate the culprit, telling you exactly which plugin to investigate, update, or replace.
  3. If disabling all plugins didn't stop the loop, the problem is likely sitting in .htaccess itself. In WordPress, go to Settings, then Permalinks, and click Save Changes without changing anything. Expected result: WordPress regenerates a clean, default .htaccess file, which clears out any manually added rule that was causing the conflict. If you'd added custom rules on purpose, re-add them afterward one at a time so you can catch a bad one immediately.

How to see every hop in a redirect chain instead of guessing

Every fix above works best when you can actually see the chain rather than refreshing and hoping. A redirect chain is the full sequence of stops a request makes before it lands (or loops): each hop has its own status code and a Location header telling the browser where to go next. A loop is simply a chain where one of those Location headers points back to an address that already appeared earlier.

You can trace this yourself with a command-line tool like curl, but reading raw header output isn't fun for most site owners, and it's easy to miscount which hop is repeating. That's the gap httpcheck.tools is built to close: paste in your URL, and the report lays out every hop in order, its status code, its timing, and its Location header, so you can see precisely where the chain starts repeating. It's also how you confirm a fix actually worked, rather than assuming it did because the page loaded once.

If you want to understand what each status code in that chain means, the site's status code reference breaks down the difference between a 301, a 302, and the less common 307 and 308 redirects you might spot along the way. And if a hop's headers look unfamiliar, the header-by-header guide explains what each one is doing there.

Google's own guidance on redirects covers how 301s and canonicalization should behave for crawlers, but stops short of publishing an exact number of hops Googlebot will follow before giving up (Google Search Central). Figures like "10 hops" or "5 hops" circulate across SEO blogs, but none trace back to an official Google statement. The practical target either way is the same: keep any necessary chain under five hops, and use a tracer to confirm the actual count.

Frequently Asked Questions

What causes a redirect loop?

A redirect loop happens when a page's redirect instructions eventually point back to an address already visited earlier in the same request, so the browser or crawler keeps following the trail without ever reaching a final page. The four common root causes are a URL mismatch between two systems (like WordPress and your server disagreeing on http versus https), a CDN and origin server disagreeing about encryption (Cloudflare's Flexible mode), a stale cookie or HSTS policy in your browser, and a rule conflict between two plugins or a bad line in .htaccess.

How do I fix ERR_TOO_MANY_REDIRECTS?

Start by opening the site in a private or incognito window. If it loads fine there, clear cookies for that domain in your regular browser, and if that doesn't help, remove the HSTS entry for the domain (chrome://net-internals/#hsts in Chrome). If it still loops in private mode, the cause is server-side: check WordPress's Settings > General for an address mismatch, check your Cloudflare SSL/TLS mode, and if neither applies, disable your plugins one at a time to find a conflicting redirect rule.

Why does a redirect loop happen only behind Cloudflare?

This almost always comes down to Cloudflare's SSL/TLS encryption mode being set to Flexible while the origin server is separately redirecting every http request to https. Cloudflare connects to your server over plain http in Flexible mode, and if your server insists on upgrading to https, the two sides redirect each other indefinitely. Cloudflare documents this mechanism and recommends switching to Full or Full (strict) mode with a valid certificate on the origin server as the fix.

How do I see every hop in a redirect chain?

Paste the affected URL into a redirect tracing tool such as httpcheck.tools, which follows each hop individually and shows the status code, Location header, and timing for every stop. Reading that sequence in order shows you exactly which hop's Location header points back to an earlier address, which is the point where the loop forms.