Common causes
- Cloudflare SSL mode set to Flexible while the server forces HTTPS
- WordPress Site URL and Home URL disagree with the server's www or HTTPS redirect
- Duplicate HTTPS or www rules in .htaccess, Nginx and a plugin at the same time
- A load balancer terminates SSL and the app does not trust X-Forwarded-Proto
- A login or cookie check that redirects to itself
- Stale cookies or cached redirects in the browser
How to fix it
- Trace the redirect chain. Run curl -sIL https://example.com | grep -i -E '^(HTTP|location)' to see each hop. The repeating pair of URLs tells you which rules are fighting.
- Fix Cloudflare SSL mode. If you use Cloudflare, go to SSL/TLS > Overview and set the mode to Full (strict), with a valid certificate on the origin. Flexible mode causes loops with HTTPS redirects.
- Align WordPress URLs. Set WP_HOME and WP_SITEURL in wp-config.php to the exact final URL, for example https://www.example.com. They must match the server's redirect target.
- Keep one redirect rule. Pick one place to force HTTPS and www: the server config, .htaccess or a plugin. Remove duplicates from the others.
- Trust the proxy header. Behind a load balancer, check X-Forwarded-Proto before redirecting. In WordPress add if ($_SERVER['HTTP_X_FORWARDED_PROTO'] === 'https') $_SERVER['HTTPS'] = 'on'; to wp-config.php.
- Clear cookies and cache. Clear the site's cookies, purge any CDN or page cache, and test in a private window. Browsers cache 301 redirects.
Single .htaccess rule forcing HTTPS and www without a loop
RewriteEngine On
RewriteCond %{HTTPS} off [OR]
RewriteCond %{HTTP_HOST} !^www\. [NC]
RewriteRule ^ https://www.example.com%{REQUEST_URI} [L,R=301] How to stop it happening again
- Force HTTPS in exactly one place
- Use Full (strict) SSL with Cloudflare
- Update site URLs when changing domains or protocols
- Test redirects with curl after every change