Still Seeing Old Pages After a CDN Update? Troubleshoot Browser Cache, Edge Cache, and Service Workers
Create Time:2026-10-20 11:17:41
浏览量
1088

Old and new page versions travel through browser storage, CDN nodes, and a Service Worker cache.

Your deployment has finished and the origin serves the new files, but some visitors still see yesterday’s page. Purging the CDN appears to help, then another user reports the same problem. Before purging again, preserve one failing request: its complete URL, response headers, browser state, and visible build version.

The useful question is which layer returned the old content. A browser HTTP cache, an edge cache, an application cache, and a Service Worker can each retain a different version. Clearing one does not clear the others.

This guide covers websites serving HTML, JavaScript, and CSS through a CDN, including applications with Service Workers. Commands use example addresses and are diagnostic examples, not production test results. Replace them with values you are authorized to use.

Identify what is actually outdated

Start with a non-sensitive build identifier in the HTML or application interface, such as a deployment timestamp or commit reference. Record the JavaScript filenames referenced by the document.

An old document that references an earlier bundle points toward the document delivery path. A new document with current bundles but outdated account information calls for inspecting API responses and application state. Repeatedly overwriting a resource at the same URL makes these cases harder to distinguish.

Collect the following from one affected visitor and one unaffected visitor:

  • The complete URL, including query parameters, and whether the visitor is signed in.

  • The displayed build identifier and the resource URLs loaded by the page.

  • Network panel response headers and any indication of memory cache, disk cache, or Service Worker delivery.

  • Whether the failure is limited to an existing tab, device, region, or account.

Remove cookies, authorization headers, signed query strings, and personal information before sharing request captures outside a restricted support channel.

Compare the same URL at the edge and the origin

Use a GET request to collect headers while discarding the response body. This avoids assuming that HEAD and GET follow identical handling:

curl -sS -D - -o /dev/null https://www.example.com/

Record Cache-Control, Age, ETag, Last-Modified, Vary, and any provider-specific cache status headers. Age helps interpret the age of a response held by a shared cache, but does not establish whether its content is the correct release. An absent Age header does not establish that no cache was involved. Interpret vendor headers using that vendor’s documentation.

Save the body when you need to compare build identifiers:

curl -sS -D edge-headers.txt -o edge.html https://www.example.com/

# Only when you have authorized access and the origin accepts this connection:
curl -sS --resolve www.example.com:443:203.0.113.10 \
  -D origin-headers.txt -o origin.html https://www.example.com/

The IP address is reserved for documentation. --resolve changes the connection destination while retaining the URL hostname for HTTP, TLS SNI, and certificate verification. Do not add -k to turn a certificate failure into an apparent success. If the origin allows only CDN traffic, use an approved diagnostic path rather than opening its firewall to the public.

A request sent directly to the origin can still pass through an origin-side reverse proxy or application cache. If it returns old content, inspect deployment paths, upstream caches, and every instance in the origin pool. A successful update on one server does not prove that all servers have the same files.

For another comparison, request revalidation:

curl -sS -H 'Cache-Control: no-cache' -D - -o /dev/null \
  https://www.example.com/

This header requests revalidation; it is not a CDN purge command. Edge configuration determines whether the directive is honored, overridden, or forwarded. Adding random query parameters is also an unreliable bypass: a cache key may ignore them, or they may create unnecessary cache objects.

Browser HTTP caching: revalidation is different from no storage

For public HTML that should be checked before reuse, Cache-Control: no-cache is a common starting point. It permits storage but requires successful validation before reuse. no-store instructs caches not to store the response. These directives are not interchangeable.[1]

An illustrative public document response might include:

Cache-Control: no-cache
ETag: "html-build-example"

The ETag above illustrates syntax. The server must generate validators that accurately represent the resource. A 304 Not Modified response tells a cache to reuse its stored body after validation. That is expected behavior. If the content changed but its validator did not, an incorrect 304 can keep the previous body in use. Look for fixed ETags, misleading modification timestamps, or inconsistent validators across origin instances.

Content-fingerprinted assets, such as app.a81d9f.js, can use a different policy:

Cache-Control: public, max-age=31536000, immutable

This assumes that a changed file receives a new URL. Do not apply it indiscriminately to HTML or a continually overwritten app.js. Personalized responses require a separate privacy and shared-cache policy; public-page examples are not suitable defaults for account pages.

Changing the server’s headers cannot recall a response that a browser already holds and still considers fresh. If HTML previously received a long freshness lifetime, recovery may require waiting for expiration, a controlled migration path, or targeted instructions for affected users. Purging the CDN does not clear visitors’ local storage.

Edge caches: check the actual key and the effective rule

If the origin returns the current document while a request through the CDN returns an older build, examine the cache rule and purge record for that exact request.

Check hostnames, schemes, trailing slashes, query strings, and any device or language variants. Whether these create separate objects depends on the configured cache key. When cookies, headers, or parameters change the response, verify that the relevant variation is represented appropriately or that the response bypasses shared caching.

Inspect the effective rules rather than relying only on the origin headers. An edge rule may override origin freshness settings. Also check whether serving stale content is allowed during background revalidation or an upstream error.

stale-while-revalidate permits a stale response within its configured window while revalidation proceeds in the background. stale-if-error permits stale responses under qualifying error conditions. Both can be intentional resilience choices; neither explains indefinitely outdated content without checking the configured windows and cache behavior.[1]

Start with a targeted purge of a confirmed affected object. Compare the resulting body and build identifier before expanding the scope. A site-wide purge can increase origin load, so assess capacity and retain the previous rules before making broad changes during peak traffic.

Service Workers can return a response without the network path you expected

When command-line requests return the current page but a particular browser remains outdated, inspect Service Worker registrations and Cache Storage in the browser’s Application tools.

A Service Worker fetch handler can return a stored Cache Storage response directly. Updating HTTP cache headers does not force custom cache-first application code to fetch a fresh response. Treat HTTP caching and Cache Storage as separate parts of the investigation.

An updated worker may also remain in the waiting state while the previous worker still controls existing pages. Calling a registration’s update() initiates an update check; it does not guarantee immediate activation or control of every open page.[2][3]

skipWaiting() and clients.claim() change activation and control timing. Before using them to accelerate rollout, verify that new workers remain compatible with pages loaded under the previous release. Immediate takeover can otherwise combine old documents with incompatible new resources.

Use unregistering or clearing site data only as a controlled diagnostic action in a test browser, or with the affected user’s informed agreement. Such actions can remove offline documents, unsynchronized drafts, or local session-related state. Clearing everything is not a risk-free general repair.

The durable fix belongs in the application’s update strategy. Version cache names, remove obsolete caches owned by your application at the appropriate activation stage, and choose a document strategy suited to the product. Network-first document delivery with an offline fallback may be appropriate, while fingerprinted static files can have longer-lived caches. Do not remove another application’s caches simply because they share an origin.

Deploy in an order that keeps both old and new pages working

Before changing production behavior, retain the previous build, edge configuration, and worker version. A practical rollout sequence is to upload new fingerprinted assets first, verify that they are available through the origin and CDN, and then publish the HTML that references them.

Keep earlier assets available for a transition period that fits your traffic, cache lifetimes, and rollback requirements. Existing tabs and workers may still request them. There is no universal retention period that suits every application.

Validate these outcomes after the change:

  1. The origin and edge return the intended HTML build, and its referenced assets are reachable.

  2. A fresh browser session receives the release, while existing tabs update according to the planned behavior.

  3. Active and waiting workers match the intended rollout state, and offline fallback still works.

  4. Signed-in and anonymous responses remain isolated, and reports from affected regions have been rechecked.

If the release fails, restore the previous HTML and compatible resources, then handle edge and worker caches according to the rollback plan. Check the version delivered to an actual client after rollback; restoring origin files alone does not establish the visitor’s final state.

Close the incident with the failing request, the responsible cache layer, supporting response headers, and a verified before-and-after build comparison. That record is far more useful than a note saying that another purge seemed to help.

References

Prepared on October 20, 2026. Examples require adjustment to the actual CDN and application configuration. The MDN references were reachable during preparation; the web.dev lifecycle reference could not be retrieved in this session.

  1. MDN: HTTP caching

  2. web.dev: The service worker lifecycle

  3. MDN: ServiceWorkerRegistration.update()