mastra-ai/mastra · error · Error

Session validation failed

Error message

Session validation failed

What it means

During the SSO/OAuth callback flow, handleCallback exchanges the authorization code for a session and verifies the session cookie. When verifySessionCookie returns null the callback cannot establish a valid user session, so it throws 'Session validation failed' and the sign-in flow aborts with a 500.

Source

Thrown at auth/studio/src/index.ts:236

    return `${this.sharedApiUrl}/auth/login?${params.toString()}`;
  }

  async handleCallback(code: string, _state: string): Promise<SSOCallbackResult<StudioUser>> {
    // The shared API already consumed the OAuth code and passes the sealed
    // session directly as the `code` parameter in the redirect to this callback.
    // Validate it to get user info.
    this.logger.debug('SSO callback: validating sealed session via shared API', {
      sharedApiUrl: this.sharedApiUrl,
      codeLength: code?.length,
    });
    const user = await this.verifySessionCookie(code);
    if (!user) {
      this.logger.error('SSO callback: session validation failed — verifySessionCookie returned null', {
        sharedApiUrl: this.sharedApiUrl,
        codeLength: code?.length,
      });
      throw new Error('Session validation failed');
    }

    // Omit `cookies` so the Mastra server fallback path calls
    // createSession() + getSessionHeaders() to build a cookie scoped to
    // the deployed instance's domain.
    return {
      user,
      tokens: {
        accessToken: code,
      },
    };
  }

  setCallbackCookieHeader(_cookieHeader: string | null): void {
    // No-op: we don't use PKCE cookies — the shared API handles the full OAuth flow
  }

  getLoginCookies(): string[] | undefined {

View on GitHub (pinned to 75dd419e61)

Solutions

  1. Have the user restart the sign-in flow from the beginning (fresh authorization code)
  2. Verify session/cookie secrets are identical across all server instances and match the SSO provider config
  3. Check the logged context (sharedApiUrl, codeLength) for URL/config mismatches
  4. Wrap the callback handler to return a redirect to the login page with an error message instead of an unhandled 500

Example fix

// before
const user = await this.verifySessionCookie(code);
if (!user) throw new Error('Session validation failed');
// after (caller-side handling)
try {
  const user = await auth.handleCallback(req);
} catch (e) {
  if (e.message === 'Session validation failed') {
    return res.redirect('/login?error=session_expired');
  }
  throw e;
}
Defensive patterns

Strategy: try-catch

Validate before calling

function validateCallbackRequest(req) {
  const code = new URL(req.url, 'http://x').searchParams.get('code');
  if (!code) return { ok: false, reason: 'missing code param' };
  return { ok: true, code };
}

Type guard

function isCallbackError(e) {
  return e instanceof Error && e.message === 'Session validation failed';
}

Try / catch

try {
  const session = await auth.handleCallback(req);
} catch (e) {
  if (isCallbackError(e)) {
    return res.redirect('/login?error=session_validation_failed');
  }
  throw e;
}

Prevention

When it happens

Trigger: A user hits the /auth/callback endpoint with a code that fails verification: expired or already-used authorization code, forged/malformed code, or the shared API URL / cookie state being inconsistent so the session can't be decrypted or validated.

Common situations: User bookmarked or reloaded the callback URL (code reuse); clock skew between server and auth provider; mismatched cookie secrets across deployed instances; user hitting the callback directly without completing the SSO flow.

Related errors


AI-assisted analysis of mastra-ai/mastra@75dd419e61 (2026-08-30). Data as JSON: /api/errors/668dfd174074e782. Report an issue: GitHub.