How to Trace Redirect Loops Across the CDN Edge
A practical method for tracing redirect loops across CDNs, reverse proxies and origin applications by recording request state, headers and environment differences.
A redirect loop is often blamed on an application rule because the symptom is familiar: a client requests a URL, receives a redirect, follows it and receives another redirect to the same or an equivalent destination. In a modern delivery stack, the application may be only one participant. A CDN can terminate TLS, a reverse proxy can rewrite the host, and the origin can make a canonicalisation decision based on forwarding headers that no longer describe the public request.
The failure cannot be diagnosed reliably by inspecting one server or one URL. A useful investigation treats each request as a state transition across infrastructure layers. It compares what the client sent, what each intermediary forwarded and which layer emitted the next Location response.
What counts as a redirect loop?
An HTTP redirect is normally represented by a 3xx response with a Location field identifying where a subsequent request should be made. A 304 response is different: it is a cache-validation response, not an ordinary navigation redirect.
For diagnostic purposes, define a redirect loop as a repeated sequence of request transitions that fails to reach a stable final response. The same request state may be reached again, or normalisation may continue indefinitely because one layer keeps undoing a change made by another.
Several related symptoms need to be separated:
- A redirect chain: a finite sequence of redirects that eventually reaches a non-redirect response. It may be unnecessarily long, but it is not necessarily a cycle.
- A single incorrect redirect: one response points to the wrong destination, but that destination does not repeatedly redirect back.
- A cached response: an old redirect continues to be served after a rule has changed. This can look like a live loop even when the current request path is different.
- An application error: a 4xx or 5xx response may prevent retrieval, but it is not itself a redirect loop.
Clients also impose redirect limits. A request that exceeds that limit may be an excessive finite chain or a runaway normalisation sequence rather than a strict repeated-state cycle. The investigation should therefore locate the transition that repeats or continues, rather than simply record that a browser stopped following redirects.
Start with request state, not just the URL
A URL-only trace records too little. Two requests can display the same URL while presenting different state to the next layer. The relevant properties commonly include:
- scheme: HTTP or HTTPS;
- host, or the HTTP/2 or HTTP/3
:authorityvalue; - port;
- path and query string;
- forwarding metadata, such as
Forwarded,X-Forwarded-ProtoandX-Forwarded-Host; - cache state and cache-bypass controls;
- the edge, proxy or origin that handled the request;
- cookies, user-agent and protocol version where they may influence rules.
The standard Forwarded header can communicate information observed by an earlier proxy, including proto and host. X-Forwarded-Proto and X-Forwarded-Host are also common deployment conventions. Their trust, precedence and meaning are configuration-specific. A present header does not prove that the application trusts it, and a missing header does not prove that the application has no knowledge of the external scheme.
That distinction is central to diagnosis. A TLS-terminating CDN may know that the visitor used HTTPS while the origin receives an HTTP connection. Unless the external scheme is conveyed and trusted correctly, the application may decide that the request needs an HTTPS redirect on every pass through the stack.
Build a controlled baseline
Begin with a request that does not automatically follow redirects. This preserves the response returned by the current layer instead of reducing several transitions to a single browser error.
curl --silent --show-error --include --max-redirs 0 \
--request GET \
'https://www.example.test/products/widget' \
-H 'User-Agent: redirect-diagnostic/1.0' \
-H 'Cache-Control: no-cache'
This is a useful baseline, not a perfect reproduction of every client. curl may differ from a browser or crawler in cookies, cache state, HTTP version, TLS negotiation, method handling and user-agent-specific rules. The request header shown here is a test input, not a guarantee that every cache layer will be bypassed. Avoid using curl -I as the only test: it sends HEAD, while the affected page may behave differently for GET.
Record the response as an event rather than copying only the final URL. At minimum, capture:
- timestamp and test location;
- method and requested URL;
- status code;
- the complete
Locationvalue; - request host or authority and scheme;
- forwarding headers sent or observed;
Age,Cache-Status, provider-specific cache indicators and cache-control fields;- server,
Viaand edge identifiers where available; - request, trace or correlation IDs;
- DNS answer, resolved address, timing and protocol version where available.
Headers are evidence, not automatic attribution. A CDN or proxy may add, remove or overwrite server identifiers and forwarding fields. Request IDs that can be matched to edge, proxy and origin logs are usually stronger evidence than a Server header alone.
Trace each transition
Suppose the public request is:
https://shop.example.test/products/widget
The following synthetic trace shows how two infrastructure layers can create a loop. It is illustrative, not measured production data.
- Client to CDN: the client sends HTTPS to
shop.example.test. The CDN terminates TLS and forwards the request to the reverse proxy over HTTP. It setsX-Forwarded-Proto: httpswhile retaining the public host inX-Forwarded-Host. - CDN response: the CDN receives a 301 from the reverse proxy with
Location: https://shop.example.test/products/widgetand returns that response to the client. - Client repeats the same public request: the URL has not changed, so the CDN again connects to the reverse proxy over HTTP.
- Reverse proxy to origin: the proxy replaces the
Hostheader withorigin.internal.exampleand forwardsX-Forwarded-Proto: http, overwriting the earlier value. - Origin response: the application sees an HTTP request for its internal host. Its canonicalisation middleware redirects to the public HTTPS URL.
- Back through the CDN: the client receives the same
Locationas before and repeats the request.
Here, the public URL appears unchanged. The changing state sits behind it: the origin-facing scheme and host differ from the public scheme and host. The application is not necessarily issuing an irrational redirect. It is making a decision from metadata that does not match the intended external request.
An incident record might represent the trace like this:
Request 1 client -> CDN https://shop.example.test/products/widget
Response 301 Location: same HTTPS URL
CDN -> proxy scheme=http, Host=shop.example.test
proxy -> origin scheme=http, Host=origin.internal.example
Request 2 client -> CDN https://shop.example.test/products/widget
Response 301 Location: same HTTPS URL
CDN -> proxy scheme=http, Host=shop.example.test
proxy -> origin scheme=http, Host=origin.internal.example
The repeated public URL does not identify the emitting layer. The useful question is: which layer generated the 301, and what request state did it use?
Model host and protocol normalisation explicitly
Write down the intended canonical state before changing rules. For example:
- public scheme: HTTPS;
- public host:
shop.example.test; - public port: 443;
- origin path: unchanged;
- origin application view: external scheme HTTPS and public host, even if the transport from proxy to origin is HTTP.
Then list each normalisation rule and its input. A practical transition model can be expressed as follows:
- HTTP to HTTPS: HTTP at the public edge should transition once to HTTPS. An internal HTTP connection between a proxy and origin should not automatically be treated as evidence that the visitor used HTTP.
- www to apex, or apex to www: only one host should be canonical. Check whether the CDN, reverse proxy and application agree on which host that is.
- Alternate host to canonical host: an origin hostname used for routing may need to remain an internal routing value rather than becoming the application’s canonical host input.
- Edge-to-origin scheme: distinguish the transport scheme from the original client scheme. A proxy may use HTTP upstream while the request’s external scheme remains HTTPS.
- Port normalisation: confirm whether a non-default port is being inferred from the upstream connection rather than the public request.
For each transition, record the state before the rule, the layer applying it, the expected state after it and the resulting Location. This exposes conflicts such as an edge that enforces HTTPS, a proxy that reports HTTP to the application and an application that enforces HTTPS again.
Compare the layers without over-trusting any one test
Use controlled comparisons to narrow the fault domain. The relevant test surfaces are usually:
- Production edge: request the public hostname through the normal CDN and DNS path. This is the most important test for public behaviour.
- Cache-bypassed edge: use an agreed diagnostic query string, cache-bypass rule or provider purge process. Confirm what that control actually bypasses; a query string may affect one cache layer while leaving another unchanged.
- Staging edge: test the production-like CDN and proxy configuration against a staging origin, if available. Record configuration and ruleset versions.
- Direct origin or proxy: use this only where access is available and authorised. Preserve the relevant
Host, SNI and forwarding conditions where possible. - Specific DNS answer or backend: where load balancing is suspected, test repeatedly and record the resolved address, edge location, backend identifier and request ID.
A direct-origin response can help isolate origin or reverse-proxy behaviour, but it is not automatically representative of public production. It may bypass the CDN, public DNS, TLS termination, cache, geographic routing, host overrides or authentication. Conversely, a clean direct-origin response does not clear the origin if the public proxy sends different headers.
Compare like with like. Keep the path, method, cookies, user-agent, host and forwarding metadata controlled, and change one variable at a time. If production loops but staging does not, compare rule versions, trusted-proxy settings, environment variables, origin pools and host mappings rather than assuming the application code differs.
Check the alternative explanations
Not every repeated redirect is a live rule conflict. Include these controls in the investigation.
Cached redirects
301 and 308 responses may be cached. Age, Cache-Status and provider-specific indicators such as CF-Cache-Status can help show whether the current response came from a cache. They do not prove which configuration originally generated it. Check cache keys, purge results, browser cache and reverse-proxy cache separately.
DNS and load-balanced origins
Inconsistent DNS answers, different CDN locations or load-balanced origins can make a loop intermittent. One backend may trust X-Forwarded-Proto while another does not. Record network and backend identifiers on every request rather than treating intermittent behaviour as noise.
Trusted-proxy configuration
A framework may ignore forwarding headers unless the connecting proxy or address range is trusted. It may also trust a header that an untrusted client can supply if the edge does not overwrite it. Verify the trusted-proxy configuration, header precedence and sanitisation path in the environment where the loop occurs.
Health checks
A successful health check does not prove that a public content URL is healthy. Health checks often use a dedicated path that bypasses application middleware, canonicalisation and normal proxy handling. Test a representative content URL through the same route used by visitors.
Client-specific behaviour
Browsers, command-line tools, monitoring agents and search crawlers differ in redirect limits, cookies, cache state, method handling, HTTP version and TLS negotiation. A successful curl request is useful evidence, but it does not prove that every client sees the same response.
Separate infrastructure diagnosis from SEO interpretation
From an SEO perspective, the immediate concern is reliable retrieval. A loop can prevent a crawler or user agent from reaching a stable content response, making indexing diagnosis and post-deployment validation unreliable. That is a practical consequence of the failed request path, not a claim that every loop produces a specific ranking penalty.
The operational consequence may extend beyond the affected URL. Teams can spend time checking canonicals, sitemaps or redirect maps when the public request never reaches the application response they are inspecting. The first SEO question should therefore be whether the intended canonical URL returns a stable final response through the public delivery path.
For related work, see how to prioritise redirect chains after a migration. That is a different problem: prioritising a finite set of redirects rather than locating a multi-layer loop. Implementation work may also require coordination across technical SEO and SEO implementation.
Definition of done
Do not close the incident because one browser session eventually loads the page. A redirect-loop investigation is complete when:
- the loop or intermittent failure is reproducible, or the evidence gap is documented;
- the layer emitting each material redirect is identified through logs, request IDs or controlled comparison rather than inferred from a generic server header;
- the intended canonical destination is explicit, with one stable scheme, host and port;
- the public edge returns a stable non-redirect response for representative content URLs;
- relevant staging, production-edge, cache-bypassed and origin or proxy paths have been validated where available;
- cache state, DNS variation, load-balanced origins, trusted-proxy settings and environment-specific rules have been considered;
- the change has been tested with representative GET requests and relevant client conditions;
- monitoring or log queries can detect repeated redirects, excessive chains, cached redirect anomalies and origin inconsistency after deployment.
The useful mental model is simple: a redirect loop is not merely a list of URLs. It is a request-state transition that crosses infrastructure boundaries. Capture the state, identify the layer that changes it, compare the public and origin-facing views, and validate the fix through the path that users and crawlers actually use.
Share this article