Skip to content

CloudFront Redirect Loop: How Cached 301/302 Responses Cause Production Failures

How viewer redirects, origin redirects, cache keys and Location headers combine to create CloudFront redirect loops.

, , ,

Request Flow

Viewer requestCloudFront cache keyOrigin requestApplication canonical redirectCached 301/302

Redirect loops usually happen when CloudFront, the origin and the application disagree about host, scheme or canonical URL. Cached 301/302 responses can keep serving the mistake after the origin is fixed.

Diagnose With Curl

curl -I https://example.com/
curl -IL https://example.com/
curl -H 'Host: example.com' -I http://origin.example.internal/
  • Inspect every Location header.
  • Compare x-cache values before and after invalidation.
  • Check whether the response is from viewer policy, origin server, application code or WordPress canonical behavior.
  • Confirm whether apex and www redirect to each other.

Cache Key and Redirect Risk

If the cache key ignores query strings, host variants or headers that affect redirects, CloudFront can reuse the wrong redirect for a different request. This is especially dangerous during DNS and canonical-domain cutovers.

Permanent Fix

  • Choose one redirect owner for HTTP to HTTPS.
  • Forward the headers the application needs to determine scheme and host.
  • Align WordPress home/site URLs with the public hostname.
  • Invalidate cached redirects after the architecture is corrected.
  • Test apex, www, staging and direct CloudFront domain behavior separately.

Map Each Redirect Owner

A viewer-protocol policy, CloudFront Function, Lambda@Edge function, origin web server, framework and CMS can all issue redirects. Write down which layer owns HTTP-to-HTTPS, apex-to-www, path normalization and application canonical URLs. Two individually reasonable rules can loop when each sees a different scheme or host.

curl -sS -o /dev/null -D - https://example.com/path?probe=1
curl -sS -L --max-redirs 10 -o /dev/null -w '%{url_effective} %{http_code}n' https://example.com/
curl -sS -o /dev/null -D - https://d111111abcdef8.cloudfront.net/ -H 'Host: example.com'

Read the Headers as a Request Trace

Capture status, Location, Via, Age, X-Cache and a request ID at every hop. Age greater than zero and Hit from cloudfront indicate an edge object. A Miss does not prove the origin generated the redirect because viewer functions run before cache lookup. Compare a unique query string only when the cache policy includes it; otherwise the request can still select the same object.

Scheme disagreement behind TLS termination

CloudFront accepts HTTPS from the viewer but may use HTTP to the origin. If the origin redirects every HTTP request to HTTPS without trusting a controlled forwarded-proto signal, CloudFront repeats the HTTP origin request and receives the same redirect forever. Forward only the headers the origin needs and configure the application to trust them only from CloudFront.

Host and canonical-domain disagreement

If CloudFront forwards its distribution hostname while WordPress expects the public domain, canonical_redirect can issue a Location that another edge rule changes back. Confirm the Host origin-request setting, WordPress home and siteurl, and every apex/www function. Test each hostname independently with redirects disabled at other layers.

Understand Redirect Caching

CloudFront can cache 301 and 302 responses according to cache-control headers and the behavior TTL settings. Browsers also retain 301 responses aggressively, which makes browser-only testing misleading. First correct the configuration, then invalidate the precise affected paths, and test with curl or a clean browser profile. Invalidating before the fix simply repopulates the broken response.

Permanent Resolution Sequence

  • Choose one layer for each redirect policy.
  • Align public host and scheme information from viewer through application.
  • Keep host, query and header variance in the cache key only where response behavior depends on it.
  • Set explicit short cache controls on temporary redirects during migration.
  • Invalidate affected objects after configuration is deployed.
  • Test every public hostname, representative path, query route and POST endpoint.

Validation Matrix

RequestExpectedEvidence
HTTP public hostOne redirect to HTTPSSingle Location header
HTTPS canonical host200 responseNo redirect; correct canonical
Alternate hostOne canonical redirectStable destination
Search queryDistinct 200 responseQuery-aware cache behavior
POSTUncached application responseNo edge redirect replay

Prevent Regression During Cutovers

Treat redirects as versioned routing logic. Keep a hostname and path test matrix in CI, log edge function changes, use temporary 302 responses until the destination is proven, and retain an explicit rollback for DNS and application canonical settings. A successful homepage check is insufficient because a cached redirect can be path-specific.

A Safe Incident Runbook

Freeze DNS, cache policy and application canonical changes while the loop is mapped. Capture one request with redirect following disabled, then follow at most ten hops and write down each status, Location, Age and X-Cache value. Repeat for HTTP and HTTPS, canonical and alternate hostnames, a known static path, an application path and a unique query. The point is to identify the first incorrect transition, not the final browser error.

Inspect the CloudFront behavior that matches the failing path, not only the default behavior. Record viewer protocol policy, cache policy, origin request policy, function associations, origin protocol policy and custom headers. A static behavior and a dynamic behavior can have different redirect owners. Check deployment status and function publication versions so the console configuration you see is actually the configuration serving requests.

WordPress and Reverse-Proxy Details

WordPress derives canonical URLs from home, siteurl and request variables. Behind a proxy, HTTPS detection often depends on a forwarded-proto value. Set that value at a trusted boundary and normalize it before WordPress runs; never accept an arbitrary viewer header as proof of scheme. Review web-server rules, plugins and wp-config.php for duplicate redirects. Multisite and domain-mapping configurations add another canonical layer and need hostname-specific tests.

NGINX redirects should use the public host intentionally. A rule based on $host can reflect an unexpected forwarded hostname, while a hard-coded host can send staging traffic to production. If CloudFront uses HTTPS-only to the origin, confirm the origin certificate covers the configured origin name. If it uses HTTP, do not let the origin redirect that trusted CloudFront hop merely because it is HTTP; use the controlled viewer-scheme signal for public canonical logic.

Cache-Control During Migration

Use 302 or 307 with a short explicit cache lifetime while validating a domain or path migration. Move to 301 or 308 only after the request matrix has remained correct and rollback is no longer expected. Remember that an edge invalidation cannot clear a browser’s remembered permanent redirect. Change the test path or use a clean profile when separating browser state from edge state, and communicate that distinction to support teams.

Rollback Without Creating a Second Loop

A rollback should restore one coherent redirect architecture, including edge function version, behavior policies, origin configuration and application URL settings. Rolling back only WordPress while leaving a newly published edge function can invert the loop. Keep the prior values and deployment identifiers together. After rollback, invalidate only the affected paths, wait for completion, and rerun the same matrix rather than relying on a single successful homepage request.

Prevent recurrence with automated assertions for hop count, exact Location host and scheme, canonical metadata and cache headers. Run them against the distribution hostname with an explicit Host header where supported, as well as the public DNS names. Alert on unusual growth in 3xx responses by behavior. Redirects are production routing code and deserve review, versioning and staged rollout like application code.

Questions to Answer Before the Incident Closes

For every hostname, document the authoritative redirect owner, expected status and destination. Include HTTP, HTTPS, apex, www, staging, CloudFront distribution host, health paths, search queries, static assets and administrative routes. Verify that canonical and Open Graph URLs agree with the final public host. Check cookies and authentication because a redirect can appear fixed for anonymous traffic while logged-in users follow a different behavior. Confirm that POST, API and admin paths use caching-disabled behaviors and never replay a cached redirect. Store the resulting matrix beside the CloudFront and application configuration so later changes update both.

Review how the bad response reached production. If a function or policy changed without a path-level test, add a deployment gate. If WordPress values changed independently from edge configuration, define an owner and order for future cutovers. Record invalidation ID, completion time and the first clean response from more than one edge location where practical. Keep redirect TTLs short during planned migrations and monitor 3xx rates by hostname and path. The final check is not simply that curl reaches 200: it is that each supported entry point takes the intended number of hops, produces a stable cache key and can be rolled back coherently.

Test error responses and origin unavailability as part of the redirect model. A custom error page, origin failover group or maintenance function can introduce a Location header that normal-path checks never see. Confirm that health checks use a path exempt from application canonical behavior and that alternate origins share the same public-host assumptions. Review response-header policies separately from cache policies: security headers should remain consistent on redirects without turning user-specific responses into shared objects. Keep a small uncached diagnostic endpoint that reports the trusted host and scheme interpretation without exposing secrets, then remove or restrict it after the migration window. Repeat the matrix after certificate renewal and origin replacement because host validation and protocol changes can reactivate an old redirect rule. Record the expected result in monitoring so future operators can distinguish deliberate canonical redirects from a recurrence.

Need help with a similar issue?

Bring the symptoms, logs and constraints. I will help separate recovery steps from permanent fixes.