vercel/ai · error

Unsupported client authentication method: ${method}

Error message

Unsupported client authentication method: ${method}

What it means

applyClientAuthentication switches on the client's configured token_endpoint_auth_method. The library supports 'client_secret_basic', 'client_secret_post', and 'none'; any other value falls through to the default case and throws. This indicates an unsupported/unknown client authentication method was supplied in client information or metadata.

Source

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

  method: ClientAuthMethod,
  clientInformation: OAuthClientInformation,
  headers: Headers,
  params: URLSearchParams,
): void {
  const { client_id, client_secret } = clientInformation;

  switch (method) {
    case 'client_secret_basic':
      applyBasicAuth(client_id, client_secret, headers);
      return;
    case 'client_secret_post':
      applyPostAuth(client_id, client_secret, params);
      return;
    case 'none':
      applyPublicAuth(client_id, params);
      return;
    default:
      throw new Error(`Unsupported client authentication method: ${method}`);
  }
}

function applyBasicAuth(
  clientId: string,
  clientSecret: string | undefined,
  headers: Headers,
): void {
  if (!clientSecret) {
    throw new Error(
      'client_secret_basic authentication requires a client_secret',
    );
  }

  const credentials = btoa(`${clientId}:${clientSecret}`);
  headers.set('Authorization', `Basic ${credentials}`);
}

View on GitHub (pinned to 69428b1f8b)

Solutions

  1. Set the client's token_endpoint_auth_method to one of 'client_secret_basic', 'client_secret_post', or 'none' in the stored OAuthClientInformation or registration request.
  2. If the AS forces private_key_jwt / client_secret_jwt, reconfigure the AS client to allow client_secret_post or client_secret_basic.
  3. Check for typos in a hand-crafted clientInformation object and fix the method string.
  4. Re-register the client (invalidate stored credentials via provider.invalidateCredentials('all')) so registration negotiates a supported method.

Example fix

// before
const clientInformation = { client_id: 'abc', token_endpoint_auth_method: 'private_key_jwt' };
// after
const clientInformation = { client_id: 'abc', client_secret: 'shhh', token_endpoint_auth_method: 'client_secret_post' };
Defensive patterns

Strategy: validation

Validate before calling

const SUPPORTED = ['client_secret_basic', 'client_secret_post', 'none'];
const method = clientInformation.token_endpoint_auth_method ?? 'client_secret_basic';
if (!SUPPORTED.includes(method)) {
  throw new Error(`Reconfigure client: MCP supports only ${SUPPORTED.join(', ')}, got ${method}`);
}

Type guard

function hasSupportedAuthMethod(m: unknown): m is { token_endpoint_auth_method: 'client_secret_basic' | 'client_secret_post' | 'none' } {
  return !!m && typeof m === 'object' && ['client_secret_basic', 'client_secret_post', 'none'].includes((m as any).token_endpoint_auth_method);
}

Try / catch

try {
  await auth(provider, { serverUrl });
} catch (error) {
  if (String(error.message).startsWith('Unsupported client authentication method')) {
    await provider.invalidateCredentials?.('all'); // re-register with a supported method
  }
}

Prevention

When it happens

Trigger: Calling exchangeAuthorization or refreshAuthorization (via auth()) where the resolved client auth method (from OAuthClientInformation/registration response, e.g. token_endpoint_auth_method) is something like 'client_secret_jwt', 'private_key_jwt', or any typo'd value.

Common situations: Dynamically registering a client against an AS that responds with a JWT-based auth method (private_key_jwt) the MCP client doesn't implement, or hand-writing client information with a misspelled auth method.

Understand the failure class

Related errors


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