htaccess 301 — WWW vs Apex Redirect Loops

webdev htaccess-generator tools

The site “loads forever,” then browsers report too many redirects. The postmortem is almost always the same: HTTP forced to HTTPS, HTTPS forced to www, another rule forced apex, CDN edge rules duplicated the hop, and a leftover HTTP rule bounced you back. Nobody intended a loop. Composition did it.

.htaccess redirects are powerful on Apache. They are also easy to stack until the chain is longer than your patience.

Pick one canonical shape — then enforce only that

Decide explicitly:

  • https://example.com or https://www.example.com
  • Never both as equals
  • HTTP always upgrades to HTTPS on the canonical host

Document the choice in DNS (A/ALIAS vs CNAME) and in Search Console. Redirects should match that story, not invent a second one.

Example: apex is canonical.

RewriteEngine On

# HTTPS first (avoid host flip while still on HTTP when possible)
RewriteCond %{HTTPS} !=on
RewriteRule ^ https://%{HTTP_HOST}%{REQUEST_URI} [L,R=301]

# Then www → apex on HTTPS
RewriteCond %{HTTP_HOST} ^www\.example\.com$ [NC]
RewriteRule ^ https://example.com%{REQUEST_URI} [L,R=301]

Example: www is canonical — flip the host rule accordingly. Do not enable both “add www” and “strip www” files from different tutorials.

Generate a reviewed snippet with an htaccess redirect generator if you want fewer typos than copy-pasting from three Stack Overflow answers.

Test the chain, not just the final URL

curl -I http://example.com
curl -I http://www.example.com
curl -I https://www.example.com

You want a short chain: ideally one 301 to the final HTTPS canonical URL. Two hops (HTTP→HTTPS on same host, then host normalize) can be acceptable. Five hops is a smell. A cycle is an outage.

Chrome caches 301s aggressively. After fixing rules, test with curl or a private session, and temporarily use 302 while iterating so you do not poison caches.

Platform gotchas

This is Apache. Nginx ignores .htaccess. On Nginx you need return 301 / rewrite in the server block. Dropping an .htaccess on a Nginx host does nothing — or confuses the next person who thinks redirects are “already configured.”

CDN / host panels. Cloudflare Page Rules, Netlify _redirects, Vercel redirects, and cPanel “Force HTTPS” can duplicate .htaccess. Prefer one enforcement point closest to the edge or closest to the origin — not both fighting.

Trailing slash and index rules. Separate content redirects from host canonicalization. Mixing DirectorySlash, RewriteRule for marketing URLs, and host rules in random order creates surprising loops.

Ordering mental model

  1. Terminate TLS / HTTPS upgrade
  2. Normalize host (www vs apex)
  3. Path-level redirects (old blog slugs, etc.)

Each step should be idempotent: applying it to an already-canonical request must no-op.

A loop autopsy worth memorizing

A common failure pattern looks like this in curl -I output:

  1. http://example.com → 301 → https://www.example.com
  2. https://www.example.com → 301 → https://example.com
  3. https://example.com → 301 → https://www.example.com

Step 1 came from an old “force HTTPS + www” recipe. Step 2 came from a newer “SEO apex” recipe. Step 3 never existed alone — the CDN mirrored the apex rule incompletely. The fix is not another plugin. Delete one of the host policies until only one host remains canonical, then re-test all four entry URLs (http/https × www/apex).

Also watch for RewriteCond %{HTTPS} off behind a reverse proxy that terminates TLS. The app may see HTTP forever and keep redirecting to HTTPS, while the edge already served HTTPS. In that case use the proxy’s forwarded proto header (for example X-Forwarded-Proto) instead of %{HTTPS}, or terminate redirects at the edge only.

FAQ

301 or 302 for host canonicalization?
Use 301 once you are sure. Use 302 while testing.

Why does Google still show the www version?
Crawl delay and cached signals. Confirm rel=canonical, sitemap, and that all hops end on one host.

Can multiple RewriteRules “compose cleanly”?
Only if each condition is mutually exclusive and ordered. Blindly stacking recipes does not compose.

One canonical host, a short 301 chain, and curl verification beat any “complete htaccess SEO pack” that redirects you into oblivion.