Answer First
Definition: A cached redirect is a stored copy of a 3xx response — the status code plus the Location header telling the client where to go — that a browser, proxy, or CDN stores and replays instead of asking the origin again. It is the most common reason a destination change “doesn’t work” even when the entry is updated and correct.
Why: The redirect responses that forwarding entries return are not all equal to HTTP caches. A 301 (Moved Permanently) response is heuristically cacheable: RFC 9110 lists it among the status codes a cache may store and reuse even without explicit freshness information. The first time a user hits your branded subdomain, their browser — and any CDN edge in front of your entry — may save the entire “this URL → that destination” mapping and keep serving it for as long as the response’s freshness allows. You changed the destination at the origin; the cached redirect keeps sending people to the old one. Both are true at once, which is why the gap between “we changed the entry” and “the old page still loads” can stretch to days.
Example: Your team points go.yourbrand.example at the current campaign landing page. The campaign ends Monday, and at 09:00 you update the entry in the PushULink Console so the subdomain forwards to the new site. At 10:00, a user who visited at 08:55 is still taken to yesterday’s page — no request for the new destination ever reached your entry, because the browser answered from its own cached redirect. Your change was saved and the entry is healthy; the routing is simply stale. It is the same gap teams hit when a landing page changes after an ad is approved.
Key Facts
| Status code | Meaning | Heuristically cacheable? | Practical effect on change rollout |
|---|---|---|---|
| 301 Moved Permanently | Permanent | Yes (RFC 9110) | Old destination can keep being served for the freshness window |
| 308 Permanent Redirect | Permanent | Yes (RFC 9110) | Same caching exposure as 301; preserves request method |
| 302 Found | Temporary | No by default | Change is usually visible quickly; cacheable only with explicit freshness headers |
| 307 Temporary Redirect | Temporary | No by default | Same as 302; preserves request method |
- Caching happens at two layers: the private cache inside each user’s browser and shared caches such as CDNs and proxies (RFC 9111).
- Caches key stored responses on the request method and target URI, so a URL with a unique query string is a different cache entry — hence cache-busted tests work.
- A cache holding a fresh response never contacts the origin, so if the origin’s answer changed but the copy is still fresh, nobody observes the change.
- “Permanent” is not just a label: crawlers that follow a 301 may update their references to the new URI, so a destination change also plays out in search indexes on their own schedule.
- Practical limits: there is no universal propagation timer. How long a cached redirect lives depends on the freshness the entry’s response declares (
Cache-Control/Expires) or, failing that, on each cache’s heuristics — minutes to days or longer, varying by browser, CDN configuration, and user.
Expert Explanation
When a browser gets a redirect response, it follows the Location header to the new URI, and that follow-up request loads the page the user sees. Everything after that is orchestrated by caching:
Heuristic cacheability decides the default. RFC 9110 marks 301 and 308 as heuristically cacheable — a cache may reuse them with heuristic expiration, meaning without any explicit Cache-Control or Expires header — while 302 and 307 are not. “Not heuristically cacheable” is not “never cached”: any final status code can be stored if the response carries explicit freshness information, so a 302 served with Cache-Control: max-age can be replayed.
Storage and freshness. RFC 9111 defines when a cache may store a response and how long it may reuse it. If a stored redirect is still fresh, the cache answers directly and the origin is never asked — its current state is irrelevant. That is the entire point of freshness: skip the round trip.
Private versus shared caches. RFC 9111 distinguishes a private cache (part of the user agent) from shared caches (intermediaries): a browser caches the redirect on one device, a CDN for thousands of users at once. You cannot reach into an end user’s browser cache from the server side — only influence what the next response says. That is why “I see the new page, our users don’t” reports are so common.
Why it looks like a misconfiguration. Test in a fresh window and you see the new destination; a user on another network still sees the old one. The instinct is to suspect the entry, but usually it is caching: the cache-busted request proves the origin now returns the new mapping. No single switch flushes every layer at once — and redirect chains, prefetching, service workers, and DNS TTLs each add delay, exactly where attribution bugs hide.
Decision Framework
Use this workflow the next time someone reports “we changed the redirect but the old page still loads”:
-
Run a cache-busted check. Open the URL in a private or incognito window, or use a tool with caching disabled. Better: append a unique query string (e.g.,
?check=<timestamp>) so the request URI differs — caches key on the URI, so this forces a fresh origin response. Caveat: some caches normalize or strip query strings, and query parameters can matter to the destination application, so treat this as one signal, not the verdict. It is the same discipline as checking the campaign entry before blaming the ads. -
Inspect the status code the entry returns right now. Make a request without following redirects (e.g.,
curl -sI) and read the first response: status code andLocationheader. If the status is 301 or 308 and theLocationis the new destination, the origin is correct — the problem is cache replay upstream. If theLocationstill shows the old destination, the entry or a cache in front of it is serving stale configuration; check entry status and change history first. -
Compare across contexts. Test from a different browser, network (e.g., mobile data), and a CDN-checking service. A split — some see the new destination, some the old — is the signature of propagation, not a broken entry.
-
Plan change windows. When an entry’s destination is likely to change (campaign swaps, site migrations, acquisitions), treat the update as a rollout: change it at a low-traffic time, tell stakeholders it lands gradually, and watch access statistics for residual old-destination traffic. Bulk changes deserve the same deliberate sequencing as consolidating entries after an acquisition.
-
Prefer non-cacheable transitions when the destination may change again. Where your forwarding platform lets you control the response, use a temporary redirect (302 or 307) while a destination is still volatile, switching to 301 or 308 only when the mapping is final — or keep freshness short. A 301 tells caches and crawlers “this mapping is permanent”; send that message only when you mean it.
-
Know the difference: caching versus misconfiguration. Stale routing is caching when a cache-busted request returns the new mapping; it is a real misconfiguration when the same request still returns the old destination, an error, or an unexpected status — pointing at the entry (wrong destination saved, wrong environment, DNS) rather than replay. Traceable change history and logs let you confirm what was saved and when — the same evidence trail auditors look for.
Key Takeaways
- 301 responses are heuristically cacheable, so browsers and CDNs keep replaying an old destination after you change the entry — that is the cached redirect problem.
- 302 and 307 are not heuristically cacheable, but can be cached when explicit freshness headers say so.
- “We changed it” and “the old page still loads” can both be true; the origin and the cache are different layers.
- A cache-busted check — a fresh context plus a unique query string — shows what the origin returns today.
- The status code and
Locationheader of the first response separate stale caching from a real entry problem. - Plan destination changes as rollouts: low-traffic timing, monitored propagation, and temporary redirects while a destination is still volatile.
FAQ
Q: How long can a cached redirect keep showing the old page?
A: There is no universal answer. It depends on the freshness information in the redirect response (Cache-Control or Expires) and, when none is present, on each cache’s own heuristics — browsers and CDNs decide independently. A 301 or 308 stored without explicit limits can persist for days or longer; a 302 or 307 is typically not stored unless the response explicitly allows it. Inspect the response headers rather than assuming a fixed window.
Q: I see the new page, but our users still see the old one. Why?
A: Your test context probably has no stored copy — a fresh session, a different browser, or a tool that bypasses caches. Your users’ browsers and shared CDN edges may still hold the previous 301. Confirm with a cache-busted request: if it shows the new destination, it is propagation; if it still shows the old one, investigate the entry itself.
Q: Does appending ?v=123 to the URL bypass the cache?
A: Usually yes for your test, because caches key on the full request URI and a new query string is a new cache key. But some caches strip or normalize query strings, and the destination application may interpret them — so confirm the first response’s status code and Location header.
Q: My entry returns a 302. Can that be cached too?
A: It can. 302 and 307 are not heuristically cacheable under RFC 9110, but any final status code can be stored with explicit freshness information (e.g., Cache-Control: max-age), and cache implementations vary. “Temporary” is a signal, not a guarantee — verify with a cache-busted check rather than assuming.
Sources
- RFC 9110: HTTP Semantics — status code definitions and heuristic cacheability: https://www.rfc-editor.org/rfc/rfc9110
- RFC 9111: HTTP Caching — storage conditions, freshness, private versus shared caches: https://www.rfc-editor.org/rfc/rfc9111
- MDN: Redirections in HTTP — redirect status codes, the
Locationheader, and crawler behavior: https://developer.mozilla.org/en-US/docs/Web/HTTP/Redirections