One morning our marketing site's homepage started failing with ERR_TOO_MANY_REDIRECTS. Every other page was fine. The cause turned out to be a perfectly reasonable cache setting meeting a perfectly reasonable SEO plugin. Here's the chain, because it's an easy one to walk into.
The two reasonable settings
1. The SEO plugin strips tracking parameters. Our WordPress site (bytephase.com) uses Yoast, which can 301-redirect /?fbclid=abc or /?utm_source=x to the clean URL /. That's good for duplicate-URL hygiene.
2. The CDN ignores tracking parameters in the cache key. In CloudFront we excluded utm_*, gclid, fbclid and msclkid from the cache policy. Otherwise every ad click creates a fresh cache entry and a cache miss. Also good.
How they combine
- A visitor arrives at
/?fbclid=abc. - CloudFront drops
fbclidfrom the cache key, so the request maps to the cache entry for/. But the origin request policy still forwardsfbclidto WordPress. - WordPress sees the parameter and answers
301 → /. - CloudFront caches that 301… under the key for
/. - The next visitor requests
/, gets the cached301 → /, follows it, and gets the same 301. Loop.
The homepage was the only victim because it's where ad and social traffic lands.
The fix
The cache key and the origin request must agree on which parameters exist. If CloudFront ignores a parameter for caching, it must also not forward it to the origin.
We switched the origin request policy from "all viewer query strings" to all except the same list the cache policy excludes:
utm_source, utm_medium, utm_campaign, utm_term,
utm_content, utm_id, gclid, fbclid, msclkid
Now WordPress never sees fbclid, so it never issues the redirect, and nothing poisonous gets cached. Analytics still works, because GA reads the parameters client-side from the browser URL, not from the server.
Then we invalidated /*.
Two gotchas while verifying
-
Your browser caches 301s too. After the edge was fixed, Chrome kept looping from its own redirect cache. Test with a fresh profile, or
fetch(url, {cache: 'reload'}), before declaring it still broken. - The loop can return quietly. Add a parameter to the cache-key exclusions later without adding it to the origin exclusions, and the same chain re-forms. We now keep the two lists side by side in the same change.
Takeaway
Any time a CDN normalises a request (drops parameters, headers or cookies from the cache key), ask: can the origin answer differently based on the thing I just dropped? If yes, either keep it in the key or stop forwarding it. Redirects are the worst case, because they're cacheable and they point at themselves.
We build repair shop management software at BytePhase. The marketing site is WordPress behind CloudFront, and we write up the infrastructure lessons here as we hit them.

Top comments (0)