You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
After step 6, the page renders the SSR placeholder (SSR placeholder ⏳) and never updates.
No console errors, no unhandledrejection, no failed network requests.
DevTools → Network: the localhost document is served 200 (from disk cache) with Cache-Control: no-cache, must-revalidate. All JS chunks are also (from disk cache).
React never hydrates. useEffect never fires. Inline <script> tags in <head>do run (so the document executed scripts), but the Turbopack RSC bootstrap leaves the tree un-mounted.
A real-world consequence in our app: a full-screen loading placeholder rendered by SSR remains visible indefinitely; users have to manually refresh.
Expected behavior (matches 16.0.x):
Back/forward should leave the page hydrated and interactive (or trigger a normal new request that hydrates correctly).
Verified that downgrading next to 16.0.9 makes the bug disappear. Network shows Cache-Control: no-store, must-revalidate on the document, Chrome cannot serve it from disk cache on back/forward, and the page hydrates as expected.
Chrome's back/forward navigation is allowed by HTTP/1.1 (and is the documented Chrome behavior) to bypass revalidation for Cache-Control: no-cache and serve from disk cache. With no-store, Chrome cannot disk-cache the response, so this code path is avoided entirely.
The disk-cached HTML carries __next_f.push(...) chunks tied to a specific dev-server session/build. When Turbopack's RSC bootstrap tries to consume this stale payload, hydration silently no-ops with no error surfaced.
So while the header change itself is intentional per #91503, it has an unintended interaction with Chrome's back/forward cache semantics that breaks dev-mode UX.
Provide environment information
Operating System:
Platform: darwin
Arch: arm64
Version: Darwin Kernel Version 25.5.0: Mon Apr 27 20:41:26 PDT 2026; root:xnu-12377.121.6~2/RELEASE_ARM64_T8132
Available memory (MB): 32768
Available CPU cores: 10
Binaries:
Node: 24.13.0
npm: 11.6.2
Yarn: N/A
pnpm: 10.28.2
Relevant Packages:
next: 16.2.3 // There is a newer version (16.2.6) available, upgrade recommended!
eslint-config-next: N/A
react: 19.2.4
react-dom: 19.2.4
typescript: 5.9.3
Next.js Config:
output: N/A
Which area(s) are affected? (Select all that apply)
Turbopack, Runtime
Which stage(s) are affected? (Select all that apply)
next dev (local)
Additional context
Tested on Chrome (incognito + with extensions disabled — same result, rules out extensions).
Production build (next build && next start) is unaffected.
A workaround for app-level fix while waiting for upstream:
// app/layout.tsx — dev onlyif(process.env.NODE_ENV==="development"){// inline script in <head>// window.addEventListener('pageshow', e => {// if (e.persisted) return;// const nav = performance.getEntriesByType('navigation')[0];// if (nav?.type === 'back_forward') location.reload();// });}
Setting Cache-Control: no-store from next.config.ts headers() or middleware does not override the dev-server-injected header — Next.js dev rewrites it on the response.
Link to the code that reproduces this issue
https://github.com/broBinChen/next-1623-bfnav-disk-cache-repo
To Reproduce
Current vs. Expected behavior
Current behavior (16.1+ / 16.2.3 verified):
SSR placeholder ⏳) and never updates.unhandledrejection, no failed network requests.localhostdocument is served200 (from disk cache)withCache-Control: no-cache, must-revalidate. All JS chunks are also(from disk cache).useEffectnever fires. Inline<script>tags in<head>do run (so the document executed scripts), but the Turbopack RSC bootstrap leaves the tree un-mounted.Expected behavior (matches 16.0.x):
nextto16.0.9makes the bug disappear. Network showsCache-Control: no-store, must-revalidateon the document, Chrome cannot serve it from disk cache on back/forward, and the page hydrates as expected.Suspected cause:
devCacheControlNoCacheexperimental option and hard-codedno-cachefor dev HTML responses.Cache-Control: no-cacheand serve from disk cache. Withno-store, Chrome cannot disk-cache the response, so this code path is avoided entirely.__next_f.push(...)chunks tied to a specific dev-server session/build. When Turbopack's RSC bootstrap tries to consume this stale payload, hydration silently no-ops with no error surfaced.So while the header change itself is intentional per #91503, it has an unintended interaction with Chrome's back/forward cache semantics that breaks dev-mode UX.
Provide environment information
Which area(s) are affected? (Select all that apply)
Turbopack, Runtime
Which stage(s) are affected? (Select all that apply)
next dev (local)
Additional context
next build && next start) is unaffected.