mastra-ai/mastra · error
${validationResult.error || 'invalid_token'}
Error message
${validationResult.error || 'invalid_token'} What it means
The MCP OAuth middleware validates incoming bearer tokens with the user-supplied `oauth.validateToken` callback. When that callback returns `{ valid: false }`, the middleware responds 401 with a WWW-Authenticate header whose `error` parameter defaults to `invalid_token` if the result supplies no `error` code. This is the library's enforcement point for resource-server token checks per the MCP authorization spec.
Source
Thrown at packages/mcp/src/server/oauth-middleware.ts:181
'WWW-Authenticate': generateWWWAuthenticateHeader({ resourceMetadataUrl }),
});
res.end(
JSON.stringify({
error: 'unauthorized',
error_description: 'Bearer token required',
}),
);
return { proceed: false, handled: true };
}
// Validate the token
if (oauth.validateToken) {
logger?.debug?.('OAuth middleware: Validating token');
const validationResult = await oauth.validateToken(token, oauth.resource);
if (!validationResult.valid) {
logger?.debug?.(`OAuth middleware: Token validation failed: ${validationResult.error}`);
res.writeHead(401, {
'Content-Type': 'application/json',
'WWW-Authenticate': generateWWWAuthenticateHeader({
resourceMetadataUrl,
additionalParams: {
error: validationResult.error || 'invalid_token',
...(validationResult.errorDescription && {
error_description: validationResult.errorDescription,
}),
},
}),
});
res.end(
JSON.stringify({
error: validationResult.error || 'invalid_token',
error_description: validationResult.errorDescription || 'Token validation failed',
}),
);
return { proceed: false, handled: true, tokenValidation: validationResult };View on GitHub (pinned to 75dd419e61)
Solutions
- Have the client obtain a fresh token from the authorization server and retry with the new Authorization header.
- Check the `error` code in the WWW-Authenticate response header and the 401 body to see why validateToken rejected the token.
- Verify the token's audience/resource claim matches the `resource` configured in the middleware's oauth options.
- Review your custom `validateToken` implementation for incorrect verification (wrong issuer, keys, or clock-skew tolerance).
Example fix
// before: validateToken returns { valid: false } with no error code
return { valid: false };
// after: return a specific RFC 6750 error code so clients can react
return { valid: false, error: 'invalid_token', errorDescription: 'token signature verification failed' }; Defensive patterns
Strategy: fallback
Validate before calling
const decoded = decodeJwt(token); if (decoded.exp * 1000 < Date.now()) throw new Error('token expired before request'); Type guard
function isInvalidTokenResult(r: unknown): r is { valid: false; error?: string; errorDescription?: string } { return !!r && typeof r === 'object' && (r as any).valid === false; } Try / catch
try { const res = await fetch(url, { headers: { Authorization: `Bearer ${token}` } }); if (res.status === 401) { const wwwAuth = res.headers.get('WWW-Authenticate'); const code = /error="([^"]+)"/.exec(wwwAuth ?? '')?.[1] ?? 'invalid_token'; await refreshTokenAndRetry(); } } catch (e) { logger.error('oauth request failed', e); } Prevention
- Refresh tokens proactively before expiry with a clock-skew margin.
- Assert the token audience matches the MCP server's configured resource.
- Unit-test your validateToken callback against expired/wrong-audience tokens.
When it happens
Trigger: A request reaches `createOAuthMiddleware` with a bearer token; `await oauth.validateToken(token, oauth.resource)` returns a result with `valid: false` (e.g. `{ valid: false, error: 'token_expired' }`, or no error field which yields the `invalid_token` default).
Common situations: Expired or revoked access tokens, tokens issued for a different resource/audience than `oauth.resource`, custom validators rejecting tokens due to clock skew or missing scopes, and JWTs signed by an untrusted issuer.
Related errors
- Bearer token required
- GitHub OAuth token exchange returned no token: ${data.error_
- Linear capabilities require an OAuth connection.
- Token exchange failed
- AZURE_AD_TOKEN_ERROR
AI-assisted analysis of mastra-ai/mastra@75dd419e61 (2026-08-30).
Data as JSON: /api/errors/1fd13b10de6923fb.
Report an issue: GitHub.