BerriAI/litellm · error · HTTPException

MCP upstream registration endpoint returned no usable client

Error message

MCP upstream registration endpoint returned no usable client_id

What it means

Raised after a successful-looking dynamic client registration (DCR) POST to the MCP upstream when the parsed registration response contains no usable client_id — some servers return 2xx with an error body or an unexpected shape. The registration result is unusable for subsequent authorization_code/refresh_token flows, so the ephemeral-client setup is aborted rather than cached.

Source

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

        cached_after_wait: Final = _EPHEMERAL_DCR_CLIENT_CACHE.get_cache(cache_key)
        if isinstance(cached_after_wait, EphemeralDcrClient):
            return cached_after_wait
        register_data: Final[dict[str, object]] = {
            "client_name": mcp_server.server_name or mcp_server.server_id,
            "redirect_uris": [f"{request_base_url}/callback"],
            "grant_types": ["authorization_code", "refresh_token"],
            "response_types": ["code"],
            "token_endpoint_auth_method": "none",
        }
        response: Final = await _post_dcr_registration(
            registration_url=mcp_server.registration_url,
            register_data=register_data,
            server_id=mcp_server.server_id,
        )
        try:
            registration: Final = _DcrClientRegistration.model_validate_json(response.text)
        except ValidationError as exc:
            raise HTTPException(
                status_code=502,
                detail="MCP upstream registration endpoint returned no usable client_id",
            ) from exc
        if not registration.client_id:
            raise HTTPException(
                status_code=502,
                detail="MCP upstream registration endpoint returned no usable client_id",
            )
        minted: Final = EphemeralDcrClient(
            client_id=registration.client_id,
            client_secret=registration.client_secret,
            token_endpoint_auth_method=normalize_token_endpoint_auth_method(registration.token_endpoint_auth_method),
        )
        _EPHEMERAL_DCR_CLIENT_CACHE.set_cache(cache_key, minted)
        return minted


async def resolve_ephemeral_dcr_client(

View on GitHub (pinned to 77b7c6c40c)

Solutions

  1. Check the upstream registration response; it must return a client_id.
  2. Verify the registration request payload meets the upstream requirements.

Example fix

Log the registration response body to inspect what was returned.
Defensive patterns

Strategy: try-catch

When it happens

Trigger: Thrown at litellm/proxy/_experimental/mcp_server/discoverable_endpoints.py:1516 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/d5b20fb1f51f1c95. Report an issue: GitHub.