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

  1. Have the client obtain a fresh token from the authorization server and retry with the new Authorization header.
  2. Check the `error` code in the WWW-Authenticate response header and the 401 body to see why validateToken rejected the token.
  3. Verify the token's audience/resource claim matches the `resource` configured in the middleware's oauth options.
  4. 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

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


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