mastra-ai/mastra · error
Google token response did not include an ID token
Error message
Google token response did not include an ID token
What it means
Thrown by MastraAuthGoogle.handleCallback after a successful token exchange when Google's token response JSON has no id_token field. This provider requires an OIDC ID token (it verifies it with verifyIdToken and the nonce) to build the user session, so a bare OAuth2 access-token response is unusable.
Source
Thrown at auth/google/src/auth-provider.ts:502
}),
signal: AbortSignal.timeout(10_000),
});
if (!tokenResponse.ok) {
const error = await tokenResponse.text();
throw new Error(`Google token exchange failed: ${error}`);
}
const tokens = (await tokenResponse.json()) as {
access_token: string;
id_token?: string;
refresh_token?: string;
expires_in: number;
token_type: string;
};
if (!tokens.id_token) {
throw new Error('Google token response did not include an ID token');
}
const user = await self.verifyIdToken(tokens.id_token, nonce);
const sessionData = {
user,
expiresAt: Date.now() + self.cookieMaxAge * 1000,
};
const encryptedSession = await encryptSession(sessionData, self.cookiePassword);
const cookieValue = `${self.cookieName}=${encodeURIComponent(encryptedSession)}; ${self.cookieFlags(self.cookieMaxAge)}`;
return {
user,
tokens: {
accessToken: tokens.access_token,
refreshToken: tokens.refresh_token,
idToken: tokens.id_token,
expiresAt: new Date(Date.now() + tokens.expires_in * 1000),
},View on GitHub (pinned to 75dd419e61)
Solutions
- Ensure 'openid' (plus 'email' and 'profile' as needed) is included in the scopes configured on MastraAuthGoogle / GOOGLE_SCOPES.
- Restart the sign-in flow — the missing id_token was fixed at the authorization step; the current code cannot be salvaged.
- If using custom scopes, add openid to the list rather than replacing default OIDC scopes.
- If intercepting tokens yourself, verify the token endpoint response actually contains id_token before treating the flow as complete.
Example fix
// before
new MastraAuthGoogle({ scopes: ['email', 'profile'] });
// after
new MastraAuthGoogle({ scopes: ['openid', 'email', 'profile'] }); Defensive patterns
Strategy: validation
Validate before calling
const SCOPES = ['openid', 'email', 'profile'];
if (!scopes.includes('openid')) throw new Error('Google SSO scopes must include openid so the token response contains an id_token'); Type guard
function hasIdToken(t: { access_token: string; id_token?: string }): t is { access_token: string; id_token: string } {
return typeof t.id_token === 'string' && t.id_token.length > 0;
} Try / catch
try {
const result = await provider.handleCallback(code, state);
} catch (err) {
if (err instanceof Error && err.message === 'Google token response did not include an ID token') {
// scopes were missing openid at authorization time — restart the flow with corrected scopes
return redirectTo(provider.getAuthorizationUrl(state));
}
throw err;
} Prevention
- Always include 'openid' in scopes; merge custom scopes with the OIDC defaults instead of replacing them
- If intercepting token responses yourself, assert id_token exists before proceeding
- When mocking Google's token endpoint in tests, include id_token in fixtures
- After scope changes, force users through a fresh authorization flow
When it happens
Trigger: handleCallback receives a 200 response whose body lacks id_token — typically because the original authorization request did not include the openid scope (or email/profile scopes), or a non-OIDC client configuration returned only an access token.
Common situations: Scopes configured without 'openid' (custom self.scopes overriding defaults); an admin changed scopes to only drive/calendar etc.; testing against a mocked token endpoint that omits id_token; Google account flows that skip OIDC consent.
Related errors
- Redirect URI is required for Google SSO. Set GOOGLE_REDIRECT
- Google token exchange failed: ${error}
- Redirect URI is required for SSO. Set AUTH0_REDIRECT_URI or
- State token has expired
- Redirect URI is required for SSO login
AI-assisted analysis of mastra-ai/mastra@75dd419e61 (2026-08-30).
Data as JSON: /api/errors/58fe2dfdaf1dde1d.
Report an issue: GitHub.