revalidateTag() runs after Server Action but auth() still returns stale session in RSC

3 weeks ago 15
ARTICLE AD BOX

I'm using Next.js 16 App Router with next-auth v5.

Inside my React Server Components I read the session using:

const session = await auth();

I update user data (that exists in the session payload) inside a Server Action, and after the mutation I run:

revalidateTag("user");

My user lookup is cached like this:

export const getUser = unstable_cache( async () => { const session = await auth(); return session?.user; }, ["user"], { tags: ["user"] } );

Issue

after successful mutation after calling revalidateTag("user") as well as after navigating to another route

RSCs still receive the old session data from auth().

Database is updated correctly — but auth() seems to resolve against stale cache.

The only workaround that fixes it is:

export const dynamic = "force-dynamic";

But this disables streaming and caching for the whole layout.

Questions

Is auth() cached per request in a way that is not invalidated by revalidateTag()?

If so, what's the recommended way to ensure fresh session data in RSC after a Server Action without forcing dynamic rendering?


[EDIT] - Adding the "Minimal relevant code" as requested by readers

app/layout.tsx or it can be even a server component:

import { auth } from "@/auth"; const session = await auth();

server action:

"use server"; import { revalidateTag } from "next/cache"; await updateUser(); // <--- PUT in DB revalidateTag("user");

the cached fetch function

import { unstable_cache } from "next/cache"; export const getUser = unstable_cache(async () => (await auth())?.user, ["user"], { tags: ["user"] });
Read Entire Article