nextauthjs/next-auth · error · Error

React Context is unavailable in Server Components

Error message

React Context is unavailable in Server Components

What it means

useSession relies on React Context, which is not supported in React Server Components. In next-auth v5, the react.tsx module guards this by throwing an Error when the SessionContext is undefined (i.e. the hook was called in an RSC environment). Session data must be fetched server-side with auth()/getSession instead.

Source

Thrown at packages/next-auth/src/react.tsx:138

          status: "unauthenticated" | "loading"
        }

export const SessionContext = React.createContext?.<
  SessionContextValue | undefined
>(undefined)

/**
 * React Hook that gives you access to the logged in user's session data and lets you modify it.
 *
 * :::info
 * `useSession` is for client-side use only and when using [Next.js App Router (`app/`)](https://nextjs.org/blog/next-13-4#nextjs-app-router) you should prefer the `auth()` export.
 * :::
 */
export function useSession<R extends boolean>(
  options?: UseSessionOptions<R>
): SessionContextValue<R> {
  if (!SessionContext) {
    throw new Error("React Context is unavailable in Server Components")
  }

  // @ts-expect-error Satisfy TS if branch on line below
  const value: SessionContextValue<R> = React.useContext(SessionContext)
  if (!value && process.env.NODE_ENV !== "production") {
    throw new Error(
      "[next-auth]: `useSession` must be wrapped in a <SessionProvider />"
    )
  }

  const { required, onUnauthenticated } = options ?? {}

  const requiredAndNotLoading = required && value.status === "unauthenticated"

  React.useEffect(() => {
    if (requiredAndNotLoading) {
      const url = `${__NEXTAUTH.basePath}/signin?${new URLSearchParams({
        error: "SessionRequired",

View on GitHub (pinned to a1a16a5a77)

Solutions

  1. Add "use client" at the top of the component calling useSession
  2. In server components, fetch the session with `await auth()` (v5) or `await getServerSession(authOptions)` instead
  3. Split the component: keep the server component for data, delegate session-dependent UI to a client child component

Example fix

// before
// app/profile.tsx (no directive)
import { useSession } from "next-auth/react"
const { data } = useSession()
// after
// app/profile.tsx
import { auth } from "next-auth"
export default async function Profile() {
  const session = await auth()
}
// or add "use client" to keep useSession
Defensive patterns

Strategy: type-guard

Validate before calling

// In a server component, don't use the hook; fetch directly:
// const session = await auth() // v5
// Guard: only call the hook in client components
function isClientComponent() {
  return typeof window !== "undefined" && typeof React.useContext === "function"
}

Type guard

function canUseSessionContext(): boolean {
  // SessionContext is undefined in RSC builds of the module
  return typeof window !== "undefined"
}
if (!canUseSessionContext()) {
  // use server-side auth() instead
}

Try / catch

let session
try {
  session = useSession()
} catch (e) {
  if (e.message.includes("Server Components")) {
    // render login placeholder / redirect; fetch session server-side instead
  } else throw e
}

Prevention

When it happens

Trigger: Calling the useSession hook inside a Server Component (app router component without "use client"), where React.useContext/Context is unavailable so SessionContext is undefined.

Common situations: Calling useSession in an app/ directory server component; forgetting the "use client" directive after migrating from pages router; building a shared component used in both server and client trees.

Related errors


AI-assisted analysis of nextauthjs/next-auth@a1a16a5a77 (2026-08-28). Data as JSON: /api/errors/3941e3adc6c65ad5. Report an issue: GitHub.