Skip to content

next dev 16.1+: back/forward navigation in Chrome leaves page un-hydrated due to Cache-Control change to no-cache #94036

@broBinChen

Description

@broBinChen

Link to the code that reproduces this issue

https://github.com/broBinChen/next-1623-bfnav-disk-cache-repo

To Reproduce

  1. use the linked repro
  2. pnpm dev and open http://localhost:3000/ in Chrome (verified on Chrome 138, macOS).
  3. Disable Network cache.
  4. Wait for the page to render hydrated ✅.
  5. In the URL bar, navigate away to any external site (e.g. https://example.com/).
  6. Click the browser Back button.

Current vs. Expected behavior

Current behavior (16.1+ / 16.2.3 verified):

  • 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.

Suspected cause:

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 only
    if (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.
  • Bisected by version: 16.0.9 ✅ unaffected, 16.2.3 ❌ affected. (The transition aligns with PR Remove devCacheControlNoCache experimental option (hard-code no-cache) #91503 merging into 16.1.)

Metadata

Metadata

Assignees

No one assigned

    Labels

    RuntimeRelated to Node.js or Edge Runtime with Next.js.TurbopackRelated to Turbopack with Next.js.

    Type

    No fields configured for Bug.

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions