Diagnosing Stale Rendered Content in Drupal: A Cache‑Tag Troubleshooting Guide
When edits to nodes, taxonomy, or configuration show in the admin preview but not on public pages, the culprit is often missing cache tags or contexts. This guide walks through the recognizable symptoms, diagnostic steps, fixes, and when to raise the issue.
19 Sept 2025, 01:32 UTC

Recognizable Condition
After editing a node, updating taxonomy, or changing configuration, the admin preview shows the expected markup, but public pages or anonymous users continue to display the old content. The issue is intermittent: some pages update, others stay stale, and it can vary by user role.
Common Causes
| Cause | Typical Symptom |
|---|---|
| Missing cache tags on custom render arrays or blocks | Only the admin preview updates; public pages stay stale. |
| Incorrect cache contexts (e.g., missing user role or language) | Stale content appears only for certain roles or languages. |
| Reverse proxy or CDN caching ahead of Drupal invalidation | Stale content persists until the external cache expires. |
| Third‑party modules that strip cache metadata from child render arrays | Only the parent element updates; nested fields remain stale. |
Diagnostic Checklist
- Reproduce with Caching Disabled
Log in as a privileged user and set
$config['system.performance']['cache']['debug'] = TRUE;insettings.php. Refresh the page to confirm that the stale markup disappears. If it does, caching is the root cause. - Inspect Render Array Cache Metadata
Enable
debug_cacheviaadmin/config/development/performanceor by setting$config['system.performance']['cache']['debug'] = TRUE;. Open the page source and look for thedata-drupal-cache-tagsanddata-drupal-cache-contextsattributes on the<body>tag. Verify thatnode:123andnode_listtags are present when viewing a node page. - Check Node and Entity Cache Tags
Run
drush sqlq "SELECT tag FROM cache_tags WHERE tag LIKE 'node:%'"to confirm that tags for the updated entity exist. If they are missing, a module may be overriding the default tags. - Verify Reverse Proxy Headers
Inspect the
VaryandCache-Controlheaders in the HTTP response. A CDN might be caching based onCache-Control: max-age=3600even after Drupal invalidates the tag. - Review Custom Code
Search for implementations of
hook_preprocess_HOOK()or render array builders that set['#cache']['max-age'] = 0without adding necessary tags. Also check forCacheableMetadata::createFromRenderArray()usage that discards metadata.
Fixes Tied to Findings
- Add Missing Cache Tags
In a custom block or controller, merge the required tags:
$build['#cache']['tags'][] = 'node:' . $node->id(); $build['#cache']['tags'][] = 'node_list'; - Declare Required Cache Contexts
When variation depends on user role or language, add the context:
$build['#cache']['contexts'][] = 'user.role'; $build['#cache']['contexts'][] = 'languages:language_interface'; - Purge External Cache After Invalidation
Use the CDN’s purge API or the
drush crhook to trigger a purge when a node is updated. Example for Varnish:curl -X PURGE http://your-site.example.com/* - Update Third‑Party Modules
Check for recent updates that address cache metadata. If a module intentionally sets
max-ageto zero, replace it withCacheableMetadata::createFromRenderArray()to inherit child tags. - Clear All Cache Bins After Fix
Run
drush crafter making changes to ensure the new tags are respected.
Escalation Criteria
- Stale content persists across multiple content types after all tag/context fixes and a full cache rebuild.
- The issue appears on staging and production, suggesting a core or environment problem.
- Database cache tables show lock contention or the tag invalidation queue remains unprocessed for an extended period.
- Custom code review shows no missing tags, but external CDN headers still serve stale content.
When any of these criteria are met, file a detailed issue against the relevant Drupal core or contributed module, attaching the diagnostic steps, debug output, and any relevant server logs.
0 replies
A thoughtful contribution can make all the difference. Be the first to share one.