nextjs - 💡(How to fix) Fix --experimental-build-mode=compile does not set cache headers [1 comments, 1 participants]

Official PRs (…)
ON THIS PAGE

Recommended Tools

×6

Utilities matched from this issue’s tags and category — try them while you read without losing context.

GitHub issue graph ai analysis

Paste a GitHub issue URL. We fetch that issue, discover linked issues from bodies/comments/timeline, collect linked pull requests, and produce a structured English report.

The report is written in English Markdown for sharing and archival.

Helpful · Quick feedback

Loading…
GitHub stats
vercel/next.js#83865Fetched 2026-04-08 02:21:17
View on GitHub
Comments
1
Participants
1
Timeline
6
Reactions
0
Participants
Timeline (top)
labeled ×2commented ×1issue_type_added ×1renamed ×1

Code Example

export const dynamic = "force-static";
export const revalidate = 86400;

---

next 15.5.2
RAW_BUFFERClick to expand / collapse

Link to the code that reproduces this issue

https://codesandbox.io/p/devbox/youthful-currying-9vwzgy

To Reproduce

  1. Create a root layout with:
export const dynamic = "force-static";
export const revalidate = 86400;
  1. Add some dynamic route segment, e.g. slug, later used with values unknown at build time.

  2. Run regular next build, start your production build

  3. Fetch your dynamic route, observe that Response has the header: cache-control s-maxage=86400, stale-while-revalidate=31449600

  4. Run next build --experimental-build-mode=compile, followed by next build --experimental-build-mode=generate-env (The latter would run at container startup, that's the separation of concerns that seems reasonable to me)

  5. Observe that response has header: cache-control private, no-cache, no-store, max-age=0, must-revalidate

  6. Repeat with build mode compile, but this time finish with next build --experimental-build-mode=generate

  7. Observe that the cache headers are present again.

Current vs. Expected behavior

Since these routes are not rendered at build time, the generate step should not be required in order to be able to pass cache control headers for dynamic routes. I think I understand the implication that --experimental-build-mode=compile without being followed by generate opts out of SSG/ISR into fully-dynamic and revalidate not working anymore to derive cache headers is a sideeffect, but there should be some other pattern for pages to be able to set cache headers then.

Provide environment information

next 15.5.2

Which area(s) are affected? (Select all that apply)

Dynamic Routes, Headers

Which stage(s) are affected? (Select all that apply)

next build (local), next start (local), Other (Deployed), Vercel (Deployed)

Additional context

I think this is not specific to dynamic routes and applies to fixed ones aswell, but using a dynamic route helped rule out static generation as a factor why the one build mode works while the other doesnt.

extent analysis

TL;DR

Run next build --experimental-build-mode=compile followed by next build --experimental-build-mode=generate-env to ensure cache control headers are properly set for dynamic routes.

Guidance

  • The issue seems to be related to the build mode and its impact on cache control headers for dynamic routes.
  • To mitigate this, ensure that next build --experimental-build-mode=compile is always followed by next build --experimental-build-mode=generate-env to maintain the desired cache behavior.
  • Verify that the cache control headers are correctly set by checking the response headers after running the above commands.
  • Consider exploring alternative patterns for setting cache headers in fully dynamic modes, as the current implementation relies on the generate step.

Example

No specific code snippet is provided as the issue is more related to the build process and command sequence.

Notes

The provided solution assumes that the issue is specific to the build mode and the sequence of commands. However, the user mentions that this might not be specific to dynamic routes and could apply to fixed ones as well.

Recommendation

Apply workaround: Run next build --experimental-build-mode=compile followed by next build --experimental-build-mode=generate-env to ensure cache control headers are properly set. This is because the current implementation relies on the generate step to set the cache headers correctly.

Vote matrix · Quick signals

Works
Did the solution work? Tap to confirm.
Easy Fix
Was it a quick fix?
Time Saver
Did it save you time?
Blocking
Was it severely blocking?
Common Issue
Are others likely hitting this too?
Flaky / Intermittent
Is it intermittent?
Verified / Reproducible
Can you reproduce it reliably?
Loading…

Still need to ship something?

×6

Another batch ranked right after the header list — different links, same matching logic.

Back to top recommendations

TRENDING