Serving Stale CDN Content: SWR and SIE Configuration Guide
Create Time:2026-08-17 14:21:24
浏览量
1001
微信图片_2026-08-17_123003_567.png

An expired CDN cache entry does not always have to make a user wait for the origin. The HTTP Cache-Control directives stale-while-revalidate and stale-if-error let CloudFront serve an expired response under controlled conditions. The first reduces latency while the CDN refreshes content in the background; the second improves availability when the origin is unavailable or returns an applicable server error.

These directives solve different problems. stale-while-revalidate is primarily a performance mechanism: serve the old response now and update it asynchronously. stale-if-error is a resilience mechanism: use the old response instead of passing an origin failure to the viewer. Their real behavior also depends on freshness rules, the CloudFront maximum TTL, error caching, custom error responses, and whether the object still exists at a particular edge location.

What happens after a CDN cache entry expires?

Without a stale-content policy, the first request after max-age or s-maxage expires normally triggers revalidation. CloudFront contacts the origin. If the object is unchanged, the origin can return 304 Not Modified; if it changed, the origin returns 200 OK with the new representation.

The viewer that triggers this process may have to wait for the origin. If the origin is slow, scaling, or temporarily unavailable, the delay can grow or become a 5xx response. Stale-content directives use the previously cached representation as a controlled buffer.

StageObject stateTypical behavior
Fresh periodStill within max-age or s-maxageServe directly from cache without origin validation.
SWR windowExpired but still within stale-while-revalidateServe stale content immediately and refresh it in the background.
SIE windowExpired, and the origin is unreachable or returns an applicable 5xx errorUse the stale response instead of the origin error.
All permitted windows have endedThe stale response can no longer be usedWait for the origin or return an error or custom error page.

What is stale-while-revalidate?

stale-while-revalidate, often abbreviated as SWR, lets CloudFront return an expired cached response while it asynchronously checks the origin for an updated version. The request that triggers the refresh therefore does not have to absorb the full origin latency.

Cache-Control: public, max-age=3600, stale-while-revalidate=600

This policy means:

  1. The object is fresh for the first 3,600 seconds.

  2. After it expires, a new request can receive the old version immediately while CloudFront refreshes it in the background.

  3. The SWR allowance is 600 seconds, subject to CloudFront's maximum TTL.

  4. After a successful refresh, later requests receive the new version and a new freshness period begins.

SWR is useful for article listings, product catalogs, public API results, blogs, and configuration manifests where a short period of staleness is acceptable. It is generally unsuitable for account balances, inventory reservations, one-time credentials, authorization state, or checkout prices that must be current.

What is stale-if-error?

stale-if-error, or SIE, lets CloudFront serve an expired cached response when it cannot reach the origin or when the origin returns an error in the 500–599 range. Its main purpose is availability during an origin incident, not faster routine refreshes.

Cache-Control: public, max-age=3600, stale-if-error=86400

Here, the object is normally fresh for one hour. If an applicable origin error occurs after expiration, CloudFront may use the old response during the 86,400-second SIE window. This is not a guarantee that every edge can serve the object for a full day: the old object must still be present in that edge cache, and the maximum TTL must not shorten the effective window.

SIE is not a backup system. Edge objects can be evicted because of low demand or cache-space management. Critical services still need health checks, redundant origins, origin failover, database recovery, and a tested deployment rollback process.

Can SWR and SIE be used together?

Yes. Combining them gives a more complete policy:

Cache-Control: public, max-age=3600,
  stale-while-revalidate=600,
  stale-if-error=86400

The response has three layers of behavior:

  • For the first hour, CloudFront serves a fresh cached response.

  • After expiration, it can serve the old response for up to 10 minutes while updating it in the background.

  • If the origin is unreachable or returns an applicable server error, it can use the stale response within the SIE allowance.

The two stale windows are independent directives. Do not assume they always form a simple “one hour plus ten minutes plus one day” timeline. Request timing, the revalidation result, cache residency, and the CloudFront maximum TTL all affect the outcome.

How do max-age, s-maxage, and CloudFront TTLs interact?

max-age can affect browsers and shared caches. s-maxage specifically controls shared caches such as CDNs and takes precedence for CloudFront when present. To let browsers recheck sooner while keeping an edge response fresh longer, use separate values:

Cache-Control: public,
  max-age=60,
  s-maxage=3600,
  stale-while-revalidate=600,
  stale-if-error=86400

In this example, the browser freshness period is 60 seconds and the shared CDN freshness period is 3,600 seconds. SWR and SIE describe when the selected representation may be used after that freshness period.

CloudFront cache policy values—Minimum TTL, Default TTL, and Maximum TTL—also affect the result:

  • Maximum TTL limits stale windows. CloudFront will not use a stale response longer than the smaller of the relevant stale directive and the maximum TTL.

  • Use a positive Minimum TTL carefully. CloudFront may cache a response for at least that duration even when the origin includes no-cache, no-store, or private.

  • Use stale-if-error=0 when stale fallback must be disabled. This can be appropriate for sensitive state, authorization, or fail-closed endpoints.

  • Default TTL matters mainly when the origin provides no cache lifetime. Avoid relying on one default for routes with very different freshness requirements.

How is stale-if-error different from CloudFront error caching?

MechanismWhat it serves or cachesMain purpose
stale-if-errorA previously successful response that is now expiredKeep normal content available during an origin failure.
Error Caching Minimum TTLThe origin's 4xx/5xx response or a configured custom error pageReduce repeated origin requests during an incident.
Custom error responseA predefined error page, optionally with a changed viewer status codeProvide a controlled failure experience when no stale response is available.

CloudFront caches error responses for 10 seconds by default, and the Error Caching Minimum TTL can be configured per status code. A value that is too short can amplify origin traffic during an outage; a value that is too long can keep showing an error after the origin recovers. When SIE and a custom error page both apply, CloudFront first attempts to serve eligible stale content. If none is available, it can use the configured custom error response.

Which content should be allowed to go stale?

Content typeRecommendationReason
Static articles, documentation, product informationUsually suitable for both SWR and SIEA short period of staleness is low risk and can reduce origin load.
Product listings and public catalogsUse a short SWR and evaluate SIE carefullyBalance speed against price and inventory freshness.
Public configuration or version manifestsDecide based on client compatibilityAn old version may preserve service or delay an urgent fix.
Sessions, permissions, and account profilesUsually do not cache in a shared CDNStaleness can expose private data or outdated permissions.
Payments, balances, and order submissionsDo not use stale success responses as fallbackAn incorrect business state can be worse than a clear error.
Security notices or withdrawn contentShorten or disable stale windowsOld content may delay an important correction or takedown.

How to add the Cache-Control policy at the origin

Nginx example

location /articles/ {
    add_header Cache-Control "public, max-age=300, s-maxage=3600, stale-while-revalidate=600, stale-if-error=86400" always;
}

Apache example

<Location "/articles/">
    Header always set Cache-Control "public, max-age=300, s-maxage=3600, stale-while-revalidate=600, stale-if-error=86400"
</Location>

Application response example

Cache-Control: public, max-age=300, s-maxage=3600,
  stale-while-revalidate=600, stale-if-error=86400
ETag: "article-20260817-v3"
Last-Modified: Mon, 17 Aug 2026 03:20:00 GMT

Do not apply one header to the entire site without classifying routes. Articles, account pages, APIs, downloads, and errors have different risk profiles. For responses involving cookies, authorization, or user identity, first prove that one user's content cannot be shared with another.

How to verify the configuration

1. Inspect the origin and CDN response headers

curl -I https://www.example.com/articles/test-page

Confirm that the final response contains the intended Cache-Control policy. Record Age, ETag, Last-Modified, Via, and the CloudFront cache-status header. Test the CDN URL, not only the origin, because an intermediary or response-headers policy may alter the result.

2. Observe freshness and background refresh

Use shorter values in a test environment:

Cache-Control: public, max-age=20,
  stale-while-revalidate=30,
  stale-if-error=120

Make repeated requests to populate the cache, wait for the 20-second freshness period to end, then change the origin object. Check whether the first request still returns the old response quickly and whether later requests switch to the new version.

3. Simulate an origin failure

Do this only on a controlled test distribution. First ensure that the edge has a successful cached response. Then make the test origin return 503 or become temporarily unreachable. Verify whether CloudFront serves the stale object, restore the origin, and confirm that the cache updates instead of remaining stale indefinitely.

4. Test from multiple regions

CloudFront caches are distributed across edge locations. A stale object present in one location may not exist in another. SIE therefore does not replace origin redundancy, monitoring, or deliberate cache warming.

Common configuration mistakes

Treating SWR as a scheduled proactive refresh

SWR generally still needs a request after expiration to trigger revalidation. A low-traffic object may receive no request for a long time or may be evicted earlier. Use a deployment workflow, warming, or scheduled requests when updates must occur at a precise time.

Assuming SIE covers every type of error

AWS documents SIE for an unreachable origin or an origin response in the 500–599 range. Do not assume that 401, 403, or 404 responses will automatically use an old successful response; those statuses normally represent authorization, resource existence, or request problems.

Setting response headers without checking Maximum TTL

If the CloudFront maximum TTL is shorter than the intended stale window, a large SWR or SIE value will not be fully effective. Review origin headers and the cache behavior's minimum, default, and maximum TTLs together.

Using long stale windows for real-time business data

Old prices, inventory, permissions, or security states can create business and compliance risks. Availability is not always the safest goal; when stale data can cause greater harm, an explicit failure is better than a successful but incorrect response.

Forgetting stale windows during an urgent takedown

If content must disappear immediately, do not wait for TTL, SWR, or SIE to expire naturally. Create a CloudFront invalidation and include all relevant URL, query-string, and language variants.

Recommended configuration process

  1. Classify content by risk. Decide which routes tolerate an old response and which must always use current or private data.

  2. Separate browser and CDN freshness. Use max-age and s-maxage instead of forcing all cache layers to share one lifetime.

  3. Keep SWR relatively short. It should cover normal background refresh time, not hide a long deployment failure.

  4. Align SIE with recovery objectives. Consider typical incident duration, staleness risk, and origin failover capability.

  5. Review CloudFront Maximum TTL. Ensure it does not unintentionally truncate the stale-content window.

  6. Configure error caching too. Prevent an origin request storm when stale content is unavailable.

  7. Maintain an emergency invalidation process. Operators must be able to withdraw cached content quickly.

  8. Monitor content versions. Correlate ETag, cache status, Age, origin status code, and latency to determine which version users receive.

Frequently asked questions

Will CloudFront always serve stale content after expiration?

No. The directive, time window, error condition, and cache policy must permit it, and the object must still exist in the relevant edge cache. Low-demand objects can be evicted before the configured window ends.

Will stale-while-revalidate make every user see old content?

Normally, no. CloudFront serves the old response while revalidating, then uses the updated version after a successful refresh. If refreshes keep failing, SIE, maximum TTL, and error-response settings determine what happens next.

Can stale-if-error replace multi-origin failover?

No. SIE can only use a previously cached response, does not guarantee that every edge has a copy, and cannot execute dynamic operations that require the origin. It is an additional resilience layer, not a complete failover design.

Should s-maxage and max-age be used together?

Yes, when browsers and the CDN need different freshness periods. CloudFront, as a shared cache, uses s-maxage when it is present, while browsers normally follow max-age.

How can I stop CloudFront from serving stale objects during an origin error?

AWS documents stale-if-error=0 for disabling that fallback. Also review Minimum TTL, error caching, and custom error responses so the complete behavior follows the intended fail-closed policy.

Conclusion

stale-while-revalidate and stale-if-error both allow a CDN to use expired content, but for different reasons. SWR trades a short period of staleness for lower refresh latency. SIE trades staleness for availability during an origin failure. Neither directive should be evaluated without max-age, s-maxage, CloudFront Maximum TTL, and error caching.

A sound policy starts with content risk. Static articles and public catalogs can often use controlled stale windows. Account, authorization, payment, and real-time state should be cached cautiously or explicitly use stale-if-error=0. Before production, test normal expiration, background refresh, origin 5xx responses, origin unavailability, emergency invalidation, and regional cache differences so that “stay available” never becomes “serve the wrong version indefinitely.”

References

  1. AWS CloudFront Developer Guide: Manage how long content stays in the cache (expiration), reviewed August 17, 2026

  2. AWS CloudFront Developer Guide: Control how long CloudFront caches errors, reviewed August 17, 2026

  3. IETF RFC 5861: HTTP Cache-Control Extensions for Stale Content, reviewed August 17, 2026

  4. MDN: Cache-Control, reviewed August 17, 2026