BA
Better Auth•2mo ago
oscar

🛑 Next.js 15 – “cookies inside use cache” Error in Layout Component

Hey everyone, I’m running into an issue in my Next.js 15 app when trying to fetch session data inside my DashboardLayout component. I need to pass request headers to my getSession function, but I keep getting the following error about accessing dynamic data sources inside a cache scope. I’ve tried extracting the headers outside the function and passing them as arguments, but the issue persists. Has anyone encountered this before? Any ideas on how to properly handle this while keeping caching? Here’s my current code:
import { auth } from "@/lib/auth";
import { headers } from "next/headers";

async function getSession(sessionHeaders: Headers) {
"use cache";
const session = await auth.api.getSession({ headers: sessionHeaders });
return session;
}

export default async function DashboardLayout({
children,
}: Readonly<{ children: React.ReactNode }>) {
const sessionHeaders = await headers();
const session = await getSession(sessionHeaders);

return (
<main>
{children}
<pre>{JSON.stringify(session, null, 2)}</pre>
</main>
);
}
import { auth } from "@/lib/auth";
import { headers } from "next/headers";

async function getSession(sessionHeaders: Headers) {
"use cache";
const session = await auth.api.getSession({ headers: sessionHeaders });
return session;
}

export default async function DashboardLayout({
children,
}: Readonly<{ children: React.ReactNode }>) {
const sessionHeaders = await headers();
const session = await getSession(sessionHeaders);

return (
<main>
{children}
<pre>{JSON.stringify(session, null, 2)}</pre>
</main>
);
}
Here's the error:
⨯ Error: Route /app used "cookies" inside "use cache". Accessing Dynamic data sources inside a cache scope is not supported. If you need this data inside a cached function use "cookies" outside of the cached function and pass the required dynamic data in as an argument. See more info here: https://nextjs.org/docs/messages/next-request-in-use-cache
at async getSession
4 | async function getSession(sessionHeaders: Headers) {
5 | "use cache";
> 6 | const session = await auth.api.getSession({ headers: sessionHeaders });
| ^
7 | return session;
8 | }
9 | {
environmentName: 'Cache',
digest: '1943676181'
}
⨯ Error: Route /app used "cookies" inside "use cache". Accessing Dynamic data sources inside a cache scope is not supported. If you need this data inside a cached function use "cookies" outside of the cached function and pass the required dynamic data in as an argument. See more info here: https://nextjs.org/docs/messages/next-request-in-use-cache
at async getSession
4 | async function getSession(sessionHeaders: Headers) {
5 | "use cache";
> 6 | const session = await auth.api.getSession({ headers: sessionHeaders });
| ^
7 | return session;
8 | }
9 | {
environmentName: 'Cache',
digest: '1943676181'
}
9 Replies
oscar
oscarOP•2mo ago
hey! 🙂 still having this issue
Netrifier
Netrifier•2mo ago
The 'use cache' directive caches things on the server, so it can't be used with the headers and cookies functions as these will be different for each request. To keep the caching you can enable session cache in better auth https://www.better-auth.com/docs/concepts/session-management#session-caching
Session Management | Better Auth
Better Auth session management.
oscar
oscarOP•2mo ago
i have session cache enabled but still see that the session is being fetched from the database on every refresh. what could be failing?
Netrifier
Netrifier•2mo ago
There are four checks which have to pass for the data from cookie to be returned. Possibilities are that: - the session data cookie is absent or not able to be correctly parsed - the cookieCache is disabled or the expiration time is set too low so the cookie has expired by the time it is read
if (
sessionDataPayload?.session &&
ctx.context.options.session?.cookieCache?.enabled &&
!ctx.query?.disableCookieCache
) {
if (
sessionDataPayload?.session &&
ctx.context.options.session?.cookieCache?.enabled &&
!ctx.query?.disableCookieCache
) {
Can you share your auth config file?
oscar
oscarOP•2mo ago
i used the example session cache config. maybe the session cookie is not being saved correctly.
import { betterAuth } from "better-auth";
import { prismaAdapter } from "better-auth/adapters/prisma";
import { nextCookies } from "better-auth/next-js";
import { admin } from "better-auth/plugins";
import { db } from "@/server/db";
import { env } from "@/env";

export const auth = betterAuth({
database: prismaAdapter(db, {
provider: "postgresql",
}),
trustedOrigins: [
`http://app.${env.NEXT_PUBLIC_ROOT_DOMAIN}`,
`https://app.${env.NEXT_PUBLIC_ROOT_DOMAIN}`,
],
emailAndPassword: {
enabled: true,
autoSignIn: true,
},
rateLimit: {
enabled: true,
maxRequests: 10,
perInterval: 60 * 1000, // 1 minute
},
session: {
cookieCache: {
enabled: true,
maxAge: 5 * 60, // Cache duration in seconds
},
},
plugins: [admin(), nextCookies()],
});

export type Session = typeof auth.$Infer.Session;
import { betterAuth } from "better-auth";
import { prismaAdapter } from "better-auth/adapters/prisma";
import { nextCookies } from "better-auth/next-js";
import { admin } from "better-auth/plugins";
import { db } from "@/server/db";
import { env } from "@/env";

export const auth = betterAuth({
database: prismaAdapter(db, {
provider: "postgresql",
}),
trustedOrigins: [
`http://app.${env.NEXT_PUBLIC_ROOT_DOMAIN}`,
`https://app.${env.NEXT_PUBLIC_ROOT_DOMAIN}`,
],
emailAndPassword: {
enabled: true,
autoSignIn: true,
},
rateLimit: {
enabled: true,
maxRequests: 10,
perInterval: 60 * 1000, // 1 minute
},
session: {
cookieCache: {
enabled: true,
maxAge: 5 * 60, // Cache duration in seconds
},
},
plugins: [admin(), nextCookies()],
});

export type Session = typeof auth.$Infer.Session;
i think i've solved it. could the session data cookie be failing to be saved for any reason?
lonelyplanet
lonelyplanet•2mo ago
[nextCookies(), admin()] @Netrifier
Forrest.Dev
Forrest.Dev•2mo ago
i thought it was supposed to be last in the list?
lonelyplanet
lonelyplanet•2mo ago
Your absolutely right, after looking at docs
Netrifier
Netrifier•2mo ago
have you solved it? the nextCookies() plugin must be the last one. https://www.better-auth.com/docs/integrations/next#server-action-cookies

Did you find this page helpful?