Introduction

Cloudflare's Always Online feature serves a cached copy of your website when the origin server is unreachable. While this keeps the site available during outages, the cached version may be outdated, contain broken links to dynamic resources, serve stale CSS/JS with old asset paths, or display incorrect data (out-of-stock products, expired promotions). Users may not realize they are viewing stale content, leading to confusion and potential business impact.

Symptoms

  • Site displays old content after origin goes down
  • Links in the cached page point to resources that do not exist
  • CSS and JS files are outdated, causing broken layout
  • Forms on the cached page submit to endpoints that are not functional
  • No visible indication that the user is viewing a cached/stale version

Common Causes

  • Always Online serving a cached page that is days or weeks old
  • Dynamic content (user profiles, shopping carts) cached as static HTML
  • Cached page references versioned assets that have been rotated
  • Always Online enabled without understanding its limitations
  • Stale cache not purged before origin went down

Step-by-Step Fix

  1. 1.Check if Always Online is serving stale content:
  2. 2.```bash
  3. 3.curl -sI https://example.com | grep -E "cf-cache-status|CF-RAY"
  4. 4.# Always Online responses may include a banner:
  5. 5.# "You are viewing a cached version of this page"
  6. 6.`
  7. 7.Check the Always Online status and cached version date:
  8. 8.- In Cloudflare dashboard: Caching > Configuration > Always Online
  9. 9.- Check the cached version date shown in the dashboard
  10. 10.- If stale content is problematic, consider disabling Always Online
  11. 11.Disable Always Online if stale content causes more harm than good:
  12. 12.```bash
  13. 13.curl -X PATCH "https://api.cloudflare.com/client/v4/zones/ZONE_ID/settings/always_online" \
  14. 14.-H "Authorization: Bearer API_TOKEN" \
  15. 15.-H "Content-Type: application/json" \
  16. 16.--data '{"value":"off"}'
  17. 17.`
  18. 18.Use Always Online with a custom error page instead:
  19. 19.- Create a custom 503 error page that explains the situation
  20. 20.- Configure Cloudflare Custom Pages:
  21. 21.```bash
  22. 22.curl -X PUT "https://api.cloudflare.com/client/v4/zones/ZONE_ID/custom_pages/always_online" \
  23. 23.-H "Authorization: Bearer API_TOKEN" \
  24. 24.-H "Content-Type: application/json" \
  25. 25.--data '{"url": "https://example.com/maintenance.html"}'
  26. 26.`
  27. 27.Purge stale cache before planned maintenance:
  28. 28.```bash
  29. 29.curl -X POST "https://api.cloudflare.com/client/v4/zones/ZONE_ID/purge_cache" \
  30. 30.-H "Authorization: Bearer API_TOKEN" \
  31. 31.-H "Content-Type: application/json" \
  32. 32.--data '{"purge_everything": true}'
  33. 33.# Then update the cache with a maintenance page
  34. 34.`
  35. 35.Configure Cloudflare Workers to detect origin health and serve appropriate content:
  36. 36.```javascript
  37. 37.addEventListener('fetch', event => {
  38. 38.event.respondWith(handleRequest(event.request))
  39. 39.})

async function handleRequest(request) { try { const response = await fetch(request) return response } catch (e) { // Origin is down - serve a controlled maintenance page return new Response( <html><body> <h1>Service temporarily unavailable</h1> <p>We are working to restore service. Please try again later.</p> </body></html> , { headers: { 'Content-Type': 'text/html' }, status: 503 }) } } ```

Prevention

  • Evaluate whether Always Online is appropriate for your site's content type
  • For dynamic sites, prefer custom maintenance pages over stale HTML caching
  • Set short cache TTLs for HTML pages to minimize staleness
  • Monitor Cloudflare's Always Online cached version date in regular health checks
  • Use Cloudflare Workers to implement smart origin health detection and graceful degradation