vercel/ai · error

Incompatible auth server: does not support grant type ${gran

Error message

Incompatible auth server: does not support grant type ${grantType}

What it means

During authorization code exchange, if the authorization server metadata advertises grant_types_supported and the required grant type ('authorization_code') is not in the list, exchangeAuthorization throws before making the token request. This prevents a doomed HTTP call against a server that will not honor the grant.

Source

Thrown at packages/mcp/src/tool/oauth.ts:948

    codeVerifier: string;
    redirectUri: string | URL;
    resource?: URL;
    addClientAuthentication?: OAuthClientProvider['addClientAuthentication'];
    fetchFn?: FetchFunction;
  },
): Promise<OAuthTokens> {
  const grantType = 'authorization_code';

  const tokenUrl = metadata?.token_endpoint
    ? new URL(metadata.token_endpoint)
    : new URL('/token', authorizationServerUrl);
  assertSafeOAuthEndpoint(tokenUrl);

  if (
    metadata?.grant_types_supported &&
    !metadata.grant_types_supported.includes(grantType)
  ) {
    throw new Error(
      `Incompatible auth server: does not support grant type ${grantType}`,
    );
  }

  const headers = new Headers({
    'Content-Type': 'application/x-www-form-urlencoded',
    Accept: 'application/json',
  });
  const params = new URLSearchParams({
    grant_type: grantType,
    code: authorizationCode,
    code_verifier: codeVerifier,
    redirect_uri: String(redirectUri),
  });

  if (addClientAuthentication) {
    await addClientAuthentication(
      headers,

View on GitHub (pinned to 69428b1f8b)

Solutions

  1. Enable the 'authorization_code' grant for the OAuth client in the authorization server's admin settings.
  2. Verify the metadata: curl the .well-known endpoint and confirm grant_types_supported includes 'authorization_code'.
  3. Confirm the metadata came from the intended AS (not a proxy serving stale/mismatched discovery data).
  4. Re-register the client so its allowed grant types match the MCP authorization code flow.

Example fix

// before
// { "grant_types_supported": ["client_credentials"] }
// after: enable authorization_code grant on the AS client
// { "grant_types_supported": ["authorization_code", "refresh_token"] }
Defensive patterns

Strategy: validation

Validate before calling

if (metadata?.grant_types_supported && !metadata.grant_types_supported.includes('authorization_code')) {
  throw new Error('Enable the authorization_code grant on the AS client before MCP auth');
}

Type guard

function supportsAuthorizationCodeGrant(m: { grant_types_supported?: string[] }): boolean {
  return !m.grant_types_supported || m.grant_types_supported.includes('authorization_code');
}

Try / catch

try {
  await auth(provider, { serverUrl });
} catch (error) {
  if (String(error.message).includes('does not support grant type')) {
    console.error('Enable the required grant type for this client in the authorization server admin console.');
  }
}

Prevention

When it happens

Trigger: Calling exchangeAuthorization (via auth()) with metadata whose grant_types_supported is defined and excludes 'authorization_code' — e.g. a server configured for client_credentials-only clients.

Common situations: Registering an MCP client on an AS where the client was created with only client_credentials or refresh_token grants enabled, or a metadata document misconfigured by a gateway/proxy that rewrites grant_types_supported.

Related errors


AI-assisted analysis of vercel/ai@69428b1f8b (2026-08-30). Data as JSON: /api/errors/96e78ca2dc3df4e9. Report an issue: GitHub.