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
- Read the thrown data.message — it comes from the Auth.js core response and names the real failure.
- Verify the auth route handler (toExpressRequestHandler) is mounted and the base path matches (default /auth).
- Set AUTH_SECRET in the environment of the Express process.
- 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
- Verify the auth handler is mounted and basePath matches /auth.
- Set AUTH_SECRET in all deployment environments.
- Smoke-test /auth/session with curl after deploying.
- Never assume auth() throws only on network issues — read the backend message.
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
- data.message
- data.message
- data.message
- Couldn't create session
- [createSession] Failed to fetch created session
AI-assisted analysis of nextauthjs/next-auth@a1a16a5a77 (2026-08-28).
Data as JSON: /api/errors/25104505ef2fa9f1.
Report an issue: GitHub.