BerriAI/litellm · error · MCPUpstreamAuthError
Upstream MCP server {server_name!r} returned {status_code}
Error message
Upstream MCP server {server_name!r} returned {status_code} What it means
The unified exit point for failed MCP server tool fetches: any non-auth upstream failure (classified status code included) is re-raised as MCPServerListError carrying this message. Route-level policy then relays it (single-server) or absorbs it (aggregator).
Source
Thrown at litellm/proxy/_experimental/mcp_server/faults/list_outcomes.py:109
return response.status_code, response.headers.get("www-authenticate")
return None
def raise_classified_list_failure(
exc: BaseException,
server_name: str,
suppress_challenge: bool = False,
) -> NoReturn:
"""The one place a failed server fetch chooses its carrier: an upstream 401/403 travels as
``MCPUpstreamAuthError`` with the upstream's own challenge preserved (a challenge is only ever
fabricated at the HTTP edge, and only for a 401), everything else as ``MCPServerListError`` with
a classified fault. Every fetch site delegates here so the two channels cannot drift apart per
call site. ``suppress_challenge`` is for dcr_bridge servers, whose upstream challenge points
clients at the wrong protected-resource metadata and must never relay."""
auth: Final = upstream_auth_challenge(exc)
if auth is not None:
status_code, challenge = auth
raise MCPUpstreamAuthError(
status_code=status_code,
www_authenticate=None if suppress_challenge else challenge,
server_name=server_name,
) from exc
raise MCPServerListError(classify_list_exception(exc), server_name) from exc
def classify_list_exception(exc: BaseException) -> ServerListFault:
"""Classify a per-server listing failure into exactly one outcome. Total: an exception this
function cannot recognize is the gateway's own fault (``internal``), never a re-raise."""
if isinstance(exc, MCPServerListError) and isinstance(exc.fault, ServerListFault):
return exc.fault
if isinstance(exc, MCPUpstreamAuthError):
tag: Final = "forbidden" if exc.status_code == 403 else "auth_required"
return ServerListFault(tag=tag, status_code=exc.status_code)
if isinstance(exc, TimeoutError):
return ServerListFault(tag="timeout")
if isinstance(exc, ConnectionError):View on GitHub (pinned to 77b7c6c40c)
Solutions
- Inspect the upstream server's response status and body for the cause.
- Check upstream server health and authentication.
Example fix
Check proxy logs for the upstream error detail.
Defensive patterns
Strategy: try-catch
When it happens
Trigger: Thrown at litellm/proxy/_experimental/mcp_server/faults/list_outcomes.py:109 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/a7e120c69296a41e.
Report an issue: GitHub.