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

  1. Inspect the upstream server's response status and body for the cause.
  2. 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.