nextauthjs/next-auth · error · Error

data.message

Error message

data.message

What it means

The Express adapter's getSession fetches the session from the Auth.js backend and throws Error(data.message) whenever the HTTP status is not 200. The backend's error 'message' field is used verbatim, so the surfaced message is whatever the auth core returned (e.g. UntrustedHost, fetch failure, or a session/action error). An empty body or empty object returns null instead of throwing.

Source

Thrown at packages/frameworks-express/src/index.ts:205

    req.protocol,
    // @ts-expect-error
    new Headers(req.headers),
    process.env,
    config
  )

  const response = await Auth(
    new Request(url, { headers: { cookie: req.headers.cookie ?? "" } }),
    config
  )

  const { status = 200 } = response

  const data = await response.json()

  if (!data || !Object.keys(data).length) return null
  if (status === 200) return data
  throw new Error(data.message)
}

function getBasePath(req: e.Request) {
  return req.baseUrl.split(req.params[0])[0].replace(/\/$/, "")
}

View on GitHub (pinned to a1a16a5a77)

Solutions

  1. Read the thrown data.message — it comes from the Auth.js core response and names the real failure.
  2. Verify the auth route handler (toExpressRequestHandler) is mounted and the base path matches (default /auth).
  3. Set AUTH_SECRET in the environment of the Express process.
  4. Log the full response status/body from /auth/session directly (curl it) to see the underlying error.

Example fix

// before
const session = await auth(req, res) // throws opaque Error(data.message)
// after
try {
  const session = await auth(req, res)
} catch (e) {
  console.error("Session fetch failed:", (e as Error).message)
}
Defensive patterns

Strategy: try-catch

Validate before calling

if (!process.env.AUTH_SECRET) throw new Error("AUTH_SECRET missing")
// Optionally health-check: const r = await fetch(`${origin}/auth/session`); if (!r.ok) ...

Type guard

function isSessionData(data: unknown): data is { user?: { email?: string } } & Record<string, unknown> {
  return typeof data === "object" && data !== null
}

Try / catch

try {
  const session = await auth(req, res)
} catch (err) {
  console.error("Auth.js session error (from backend):", (err as Error).message)
  // treat as unauthenticated and continue, or return 401
}

Prevention

When it happens

Trigger: Calling auth() / getSession(req) from an Express route while the backing Auth.js endpoint (/api/auth/session) responds non-200 — e.g. 401/404 because AUTH_SECRET is missing, the route handler isn't mounted, trusted host validation fails, or the core threw an internal error.

Common situations: Express apps where the auth route handler isn't correctly mounted so /auth/session 404s; AUTH_SECRET unset in production; mismatch between the Express adapter's base path and the actual handler mount point (getBasePath derives it from req.baseUrl).

Related errors


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