A redirect loop isn't a mystery. It's a configuration conflict — and it has a signature.
When your browser hits ERR_TOO_MANY_REDIRECTS, it means WordPress sent it somewhere, that destination sent it somewhere else, and then it ended up back at the start. The browser gave up after cycling through the loop a dozen times. WordPress didn't crash. Your server didn't fail. Something in the configuration is pointing at itself — and until you find that conflict, your site stays offline.
The frustrating part? Most guides tell you to "clear your cache." That's not wrong. It's just incomplete. Incomplete advice wastes time in a window where traffic is dropping, ranking signals are degrading, and your WooCommerce orders have gone silent.
The Myth: This Is a Hosting Problem
The most common assumption site owners make when they hit ERR_TOO_MANY_REDIRECTS is that the host broke something. Maybe you just migrated. Maybe you flipped on HTTPS. Maybe your host pushed a server update. So you open a support ticket, wait 45 minutes, and get back a response that says "we don't see anything wrong on our end."
They're usually right.
This error almost never lives at the infrastructure level. It lives in the application layer — which is entirely your responsibility, not your host's. Your server is working fine. WordPress is the one creating the circular logic.
The four root causes, in order of frequency:
- Mismatched
siteurlandhomevalues in the database — particularly after a migration where the old domain or protocol is still stored inwp_options - SSL/HTTPS misconfiguration — WordPress trying to force HTTPS while the server is already handling SSL termination upstream, creating a redirect cycle
.htaccessrules in conflict — usually caused by a security plugin, a caching plugin, or a poorly written custom redirect that creates a loop- A plugin forcing a redirect that contradicts WordPress core settings — Yoast, Rank Math, Redirection, and several WooCommerce extensions can all trigger this under the right (wrong) conditions
Let's work through each of these.
Start Here: The wp_options Problem
Before you touch anything else, check your database.
Open phpMyAdmin (or use WP-CLI — wp option get siteurl and wp option get home), and verify that both siteurl and home match your current live URL, including the correct protocol.
If you just migrated from HTTP to HTTPS and one of those values still reads http://yourdomain.com while the other reads https://yourdomain.com, you've found your loop. WordPress is bouncing between the two.
The fix:
wp option update siteurl 'https://yourdomain.com'
wp option update home 'https://yourdomain.com'
Simple. But the reason it happens is less simple. WordPress stores these values as serialized data in wp_options. After a migration using a tool that doesn't handle serialized data correctly — and several popular migration plugins have this issue — values can get corrupted or left pointing at the old environment entirely. You might think you updated your URLs during migration. You might not have. Or the serialization may have broken mid-write.
If you can't access the admin panel at all, add these lines to wp-config.php temporarily:
define('WP_HOME', 'https://yourdomain.com');
define('WP_SITEURL', 'https://yourdomain.com');
This forces WordPress to use those values regardless of what's stored in the database. Once your site is accessible, update the database values properly via WP-CLI and remove these lines. Don't leave them in permanently — it creates its own class of maintenance problems when you need to change URLs later.
It's also worth noting that some automated migration tools do a search-replace on the database without accounting for PHP serialized data. The string lengths in serialized arrays get corrupted. The result: options that look correct on the surface but throw unexpected redirect behavior because the serialized object is malformed. Running wp search-replace with the --dry-run flag first is how you catch this before it hits production.
The HTTPS Loop: Where SSL Termination Causes Chaos
This one is subtle and common on managed hosting or any setup where SSL termination happens at a load balancer or proxy layer — Cloudflare, Nginx, Kinsta, WP Engine, and similar environments.
Here's what happens: Your proxy handles HTTPS and passes traffic to your WordPress server as HTTP internally. WordPress doesn't know the original request was HTTPS — it just sees HTTP — so it tries to redirect to HTTPS. But the proxy already handled that. So it redirects again. Loop.
The fix involves telling WordPress the request is already secure by adding this to wp-config.php:
if (isset($_SERVER['HTTP_X_FORWARDED_PROTO']) && $_SERVER['HTTP_X_FORWARDED_PROTO'] === 'https') {
$_SERVER['HTTPS'] = 'on';
}
This tells PHP to treat the connection as HTTPS based on the forwarded header your proxy sends. Without it, WordPress perpetually second-guesses the protocol.
Some hosts require a slightly different header check. Cloudflare uses HTTP_CF_VISITOR. If you're behind Cloudflare with Flexible SSL mode enabled — meaning Cloudflare uses HTTPS externally but passes HTTP to your origin — and WordPress also enforces HTTPS via .htaccess, you now have competing redirect logic from two sources. This is one of the most common configurations that produces a loop and one of the last things people check.
The correct Cloudflare SSL mode for WordPress is Full (Strict). Full (Strict) means Cloudflare connects to your origin over HTTPS using a valid certificate. Flexible mode is a trap: it looks like it works until you turn on WordPress's force-HTTPS redirect, and then it doesn't.
.htaccess: The Silent Multiplier
Open your .htaccess file. You're looking for redirect rules that might conflict.
A common culprit looks like this:
RewriteRule ^(.*)$ https://%{HTTP_HOST}/$1 [R=301,L]
That rule redirects everything to HTTPS. Fine on its own. But if your siteurl is already HTTPS and a plugin like Really Simple SSL has also written its own redirect block above or below this rule, you now have two rules fighting for the same request.
Security plugins are repeat offenders here. Wordfence, iThemes Security, and others write .htaccess hardening rules automatically. After a migration, stale rules from the old environment often persist — and they can redirect traffic in ways that made sense before the migration but now create a loop.
The cleanest diagnostic step: rename .htaccess to .htaccess_backup and test your site. If the loop stops, the conflict lives there. Then regenerate a clean .htaccess from Settings → Permalinks (just hit Save) and reintroduce rules one at a time until you isolate the conflict.
One additional wrinkle: if your previous host used Apache and your new host uses Nginx, .htaccess rules don't apply at all under Nginx. Nginx ignores .htaccess. Instead, redirect rules must live in your Nginx server block config. If someone wrote an .htaccess HTTPS redirect for the old Apache server and your new Nginx host is handling redirects at the server config level, you may have a conflict that looks impossible to diagnose from inside WordPress — because it isn't a WordPress problem at that point.
Plugin Conflicts: The Redirect That Fires at the Wrong Layer
Disable all plugins. Not just the obvious ones. All of them.
You can do this via WP-CLI without needing admin access:
wp plugin deactivate --all
If the loop clears, you have a plugin conflict. Re-enable plugins one by one, testing after each. The loop will return when you activate the guilty plugin.
Plugins most likely to cause redirect loops post-migration:
- Redirection — stale redirect rules from the old domain
- Really Simple SSL — conflicts with server-level SSL handling
- WooCommerce — checkout/cart redirect rules can loop if
siteurlis wrong - Rank Math / Yoast SEO — canonical redirect logic conflicting with server rules
- Caching plugins (W3 Total Cache, WP Rocket) — cached redirects that don't reflect the new configuration
If your caching plugin has object cache integration — Redis or Memcached — the old redirect might be cached at the object cache layer. Flushing WordPress's database cache alone won't clear it. You need to flush the object cache directly.
For Redis:
wp cache flush
For Memcached, you'll need to restart the service or use your host's control panel. This is a step that most self-debugging attempts skip entirely, and it's why a loop can reappear minutes after you think you've fixed it.
Transients and Stale Cache: The Hidden Reinforcer
WordPress stores transient data in wp_options — including redirect-related data from certain plugins. If a plugin cached a redirect URL as a transient before your migration, and that transient hasn't expired yet, the redirect loop can persist even after you've fixed the actual misconfiguration.
Run this to clear all transients:
wp transient delete --all
Then flush your object cache if you're running one. Transients are the silent reinforcer of a loop that should already be fixed. In post-migration audits, this is one of those steps that takes 30 seconds and resolves a problem that's resisted two hours of debugging — because nobody thought to check whether an expired redirect was still being served from cache.
The Staging Workflow You Should Have Used
Here's the honest take: a redirect loop after migration almost always signals that the migration wasn't tested in a staging environment first.
Staging workflows exist precisely for this. You move the site, verify that siteurl, home, SSL handling, .htaccess, and plugin behavior all work correctly — before pointing your DNS. Migration issues on staging are free. Migration issues in production cost you traffic, rankings, and potentially revenue.
If you're running a WooCommerce store averaging even $1,000/day, downtime during a botched migration costs roughly $40/hour. A three-hour redirect loop debug session on a live site costs more than a proper staging setup and pre-migration validation would have. That math is straightforward.
A proper WordPress maintenance and migration checklist covers these validation points before you cut over DNS — not after.
The Systematic Fix: In Order
If you're mid-loop right now, work through this sequence without skipping steps:
1. Check wp_options first.
Run wp option get siteurl and wp option get home. Both must match your live HTTPS URL exactly. No trailing slashes that don't belong. No HTTP where HTTPS should be.
2. Add WP_HOME and WP_SITEURL constants to wp-config.php if you can't access the admin panel.
3. Rename .htaccess and test. If the loop clears, regenerate it from Permalinks settings.
4. Disable all plugins via WP-CLI. If the loop clears, re-enable one by one.
5. Add the HTTP_X_FORWARDED_PROTO header check to wp-config.php if you're behind a proxy or CDN.
6. Verify your Cloudflare SSL mode if applicable. Flexible mode causes loops. Full (Strict) is correct.
7. Flush transients and object cache.
Run wp transient delete --all, then flush any persistent cache layer.
Work top to bottom. Don't jump to step 5 before confirming steps 1–4. Stacking fixes without validating each step is how you end up with a configuration you don't understand.
When to Stop DIY-ing It
You've worked through the checklist. The loop is still happening. Now what?
At some point, continuing to debug a live production site means risking further misconfiguration — stacking fixes until you're not sure what's actually in your wp-config.php anymore, what's in .htaccess, and which plugins are actually active.
In post-migration recovery work, it's common to encounter sites with multiple rounds of conflicting attempts layered on top of each other, where the original issue was a one-line database fix but now there are four layers of configuration pointing in different directions. That's a harder problem to untangle than the original redirect loop.
If you've hit that wall, the right move is emergency WordPress support — not another round of forum threads.
Our WordPress care plans include pre-migration audits, staging environment setup, and post-migration validation specifically because this class of error is entirely preventable with the right process in place. Check our pricing if you want to know what that looks like as a managed service.
The Actual Risk Here
A redirect loop isn't just an inconvenience. Google's crawler doesn't wait around for you to fix it. If your site is looping at crawl time, your pages drop from the index. Depending on how long it persists, that recovery isn't automatic — crawl budget is finite, and re-indexing takes time and crawl cycles you don't control.
For WooCommerce stores or any site with advertising traffic, a loop that runs overnight without detection is a serious revenue event. Not a theoretical one.
The tools to prevent this exist. Staging environments, pre-migration checklists, monitored deployments. The reason sites end up in redirect loops isn't technical complexity — it's skipped process. The fix is rarely hard. The cost of waiting to fix it always is.
Look — I'm writing this because this is a problem I see constantly, and it's also exactly what we built Vimsy to solve. If you want professionals handling this instead of hoping nothing breaks, book a free call.
Your site should not be the place where you learn what serialized data corruption looks like.


