BerriAI/litellm · error · HTTPException

Unsupported grant_type

Error message

Unsupported grant_type

What it means

Token-exchange endpoint guard in exchange_token_with_server: the caller posted a grant_type other than authorization_code or refresh_token. It is a generic input-validation 400 raised before any upstream call.

Source

Thrown at litellm/proxy/_experimental/mcp_server/discoverable_endpoints.py:882

    return "gateway_stored" if mcp_server.client_id else "caller_supplied"


async def exchange_token_with_server(
    request: Request,
    mcp_server: MCPServer,
    grant_type: str,
    code: str | None,
    redirect_uri: str | None,
    client_id: str,
    client_secret: str | None,
    code_verifier: str | None,
    refresh_token: str | None = None,
    scope: str | None = None,
    client_token_endpoint_auth_method: MCPTokenEndpointAuthMethod | None = None,
):
    _raise_if_not_oauth2(mcp_server)
    if grant_type not in ("authorization_code", "refresh_token"):
        raise HTTPException(status_code=400, detail="Unsupported grant_type")

    if mcp_server.token_url is None:
        raise HTTPException(
            status_code=400,
            detail=_endpoint_not_configured_detail(
                mcp_server,
                "token url",
                "set Token URL manually",
                "set Issuer to discover it from the identity provider (RFC 8414)",
            ),
        )

    # The id, secret, and token-endpoint auth method must come from the same source. When the
    # server-side client_id wins, falling back to the caller's secret pairs the persisted client
    # with a foreign secret; the register short-circuit hands clients a placeholder secret
    # ("dummy"), so a re-auth against a persisted public PKCE client (no stored secret) would send
    # that placeholder and the IdP 401s. Symmetrically, a caller-side client (an ephemeral mint
    # recovered from a sealed code) must authenticate the way its own registration was granted,

View on GitHub (pinned to 77b7c6c40c)

Solutions

  1. Use a supported grant_type (authorization_code or refresh_token).

Example fix

grant_type=authorization_code
Defensive patterns

Strategy: validation

When it happens

Trigger: Thrown at litellm/proxy/_experimental/mcp_server/discoverable_endpoints.py:882 when the library encounters an invalid state.

Common situations: See trigger scenarios.


AI-assisted analysis of BerriAI/litellm@77b7c6c40c (2026-08-18). Data as JSON: /api/errors/ca0d53aa102a71f7. Report an issue: GitHub.