Next.js DynamicServerError during the Vercel build
The Vercel build throws DynamicServerError, or a static page then reads cookies at runtime? Call cookies and headers in the request's async context, or set the route's dynamic export.
Reviewed October 18, 2026
What it means in plain English
Next.js threw DynamicServerError because cookies() or headers() from next/headers ran outside the async context that started the render. The dynamic-server-error page says this happens when you call them inside setTimeout or setInterval, or after a promise you did not await. While it generates static pages, Next.js throws that error and catches it to opt the page into dynamic rendering. If the error is uncaught, the build fails.
A second message, the app/ Static to Dynamic Error, is different. The route was generated statically, then at runtime it read cookies or headers on a fallback or during revalidation. Next.js says it does not support switching between static and dynamic at runtime. The docs do not use the phrase "couldn't be rendered statically" for either error.
Awaiting cookies() and params in a Server Component is the related page params and cookies must be awaited.
Likely causes
cookies()orheaders()is insidesetTimeout,setInterval, or an event-style callback.- A promise that calls those functions was not awaited, so they run after the original context is gone.
- The page is forced static and still reads request data, or it is static at build and dynamic on a later request.
How to fix it, step by step
- Call
cookies()orheaders()directly in the Server Component or the function that is still on that call stack, and await the promise. Next.js's correct example reads the cookie store first, then starts thesetTimeoutwith the value it already has. - Do not read cookies inside the timer callback. That callback is a new execution context.
- If the build instead reports the
app/Static to Dynamic Error, stop using cookies or headers only on some requests if the other requests are static. Next.js says the mode has to be the same at build and at runtime. - Or set the route on purpose.
export const dynamic = 'force-static'keeps it static.export const dynamic = 'force-dynamic'skips static generation. Use the one that matches whether the page needs the request. - Redeploy on Vercel after the route is consistent. The build is what failed, so a runtime env change does not clear it.
How to check it worked
npm run buildfinishes withoutDynamicServerErrorand without the static-to-dynamic error.- A page that reads the session is dynamic on every request, or a page that does not need the request is static on every request.
- The deployed URL returns the page instead of the build log.
Sources
Related fixes
More Next.js errors fixes
More Vercel deploy and runtime fixes
Keep going on your own.
The guides stay free. A deep leak report is $15. Fix packs are $24, or $49 for all three. There is no done-for-you repair.