calcom/cal.diy · error · UnauthorizedException

NextAuthStrategy - Authentication token is missing or invali

Error message

NextAuthStrategy - Authentication token is missing or invalid.

What it means

Thrown by the NextAuthStrategy Passport strategy (the @nestjs/passport 'next-auth' strategy) when next-auth/jwt getToken() returns null — meaning no decodable session token was found on the request, or the signature did not validate against next.authSecret. This strategy protects routes that authenticate via the NextAuth session cookie.

Source

Thrown at apps/api/v2/src/modules/auth/strategies/next-auth/next-auth.strategy.ts:21

import { Injectable, InternalServerErrorException, UnauthorizedException } from "@nestjs/common";
import { ConfigService } from "@nestjs/config";
import { PassportStrategy } from "@nestjs/passport";
import type { Request } from "express";
import { getToken } from "next-auth/jwt";

@Injectable()
export class NextAuthStrategy extends PassportStrategy(NextAuthPassportStrategy, "next-auth") {
  constructor(private readonly userRepository: UsersRepository, private readonly config: ConfigService) {
    super();
  }

  async authenticate(req: Request) {
    try {
      const nextAuthSecret = this.config.get("next.authSecret", { infer: true });
      const payload = await getToken({ req, secret: nextAuthSecret });

      if (!payload) {
        throw new UnauthorizedException("NextAuthStrategy - Authentication token is missing or invalid.");
      }

      if (!payload.email) {
        throw new UnauthorizedException("NextAuthStrategy - Email not found in the authentication token.");
      }

      const user = await this.userRepository.findByEmailWithProfile(payload.email);
      if (!user) {
        throw new UnauthorizedException(
          "NextAuthStrategy - User associated with the authentication token email not found."
        );
      }

      return this.success(user);
    } catch (error) {
      if (error instanceof Error) return this.error(error);
      return this.error(
        new InternalServerErrorException(

View on GitHub (pinned to 176037d0af)

Solutions

  1. Forward the full Cookie header (in particular the NextAuth session cookie, default name next-auth.session-token) with the request.
  2. Ensure the `next.authSecret` / NEXTAUTH_SECRET configured on the API matches the web app that issued the cookie.
  3. If calling server-to-server, use the platform OAuth access token or an API key instead of the session cookie.
  4. Make sure the user actually has a logged-in session before the call (hit the sign-in flow first).

Example fix

// before
fetch(`${API}/next-auth-protected`, {});

// after
fetch(`${API}/next-auth-protected`, { credentials: 'include', headers: { Cookie: sessionCookie } });
Defensive patterns

Strategy: validation

Validate before calling

const cookie = getCookie('next-auth.session-token');
if (!cookie) throw new Error('No NextAuth session cookie; sign in first or use an API key');

Prevention

When it happens

Trigger: A request to a route guarded by the 'next-auth' passport strategy with no session cookie, an expired session, a tampered cookie, or a cookie signed with a different next.authSecret than the API uses.

Common situations: Calling an API route from outside the browser without forwarding the session cookie; the API's NEXTAUTH_SECRET / next.authSecret differs from the web app's; clock skew causing the JWT to be treated as expired; cookie stripped by a reverse proxy.

Understand the failure class

Related errors


AI-assisted analysis of calcom/cal.diy@176037d0af (2026-08-12). Data as JSON: /api/errors/3539e8f990b7afa9. Report an issue: GitHub.