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
- Check the upstream registration response; it must return a client_id.
- 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.