BerriAI/litellm · error · HTTPException

{fault.tag}

{fault.tag}

Error message

Failed to list tools from server {get_server_prefix(server)}

What it means

A single-server tools/list failed and the exception was classified by classify_list_exception into a ServerListFault tag (auth_required, forbidden, timeout, unreachable, upstream_error, internal). The HTTP status follows list_fault_http_status: upstream 401/403 for auth faults, 504 for timeout, 502 for unreachable/upstream_error, 500 for gateway-internal. The body carries error=fault.tag plus this message naming the server prefix. Upstream 401/403 with a challenge is re-raised separately as MCPUpstreamAuthError so WWW-Authenticate can be relayed.

Source

Thrown at litellm/proxy/_experimental/mcp_server/rest_endpoints.py:647

        try:
            list_tools_result: Final = await _get_tools_for_single_server(
                server,
                server_auth_header,
                raw_headers_from_request,
                user_api_key_dict,
                extra_headers=user_oauth_extra_headers,
                apply_tool_filters=apply_tool_filters,
            )
        except MCPUpstreamAuthError:
            # Surface the upstream 401/403 to the caller so it can emit the
            # matching status code and WWW-Authenticate challenge; that is what
            # lets standards-compliant MCP clients run the upstream OAuth flow.
            raise
        except MCPServerListError as e:
            fault: Final = classify_list_exception(e)
            verbose_logger.info("Listing tools from %s failed with a %s fault", server.name, fault.tag)
            raise HTTPException(
                status_code=list_fault_http_status(fault),
                detail={
                    "error": fault.tag,
                    "message": f"Failed to list tools from server {get_server_prefix(server)}",
                },
            ) from e
        except Exception as e:
            verbose_logger.exception("Error getting tools from %s: %s", server.name, e)
            return {
                "tools": [],
                "error": "server_error",
                "message": f"Failed to get tools from server {server.name}: {e}",
            }
        return {
            "tools": list_tools_result,
            "error": None,
            "message": "Successfully retrieved tools",
        }

View on GitHub (pinned to 77b7c6c40c)

Solutions

  1. Branch on the body's error tag: timeout -> check upstream latency/raise the client timeout; unreachable -> check URL/DNS/firewall; auth_required/forbidden -> fix the upstream credentials for that server; upstream_error -> inspect upstream logs; internal -> check proxy verbose logs.
  2. Retry only the transient tags (timeout, unreachable, upstream_error) with backoff.
  3. For fleet-wide visibility without failing the call, use the all-servers tools/list and read per-server statuses from the result _meta under litellm.ai/server_outcomes.
Defensive patterns

Strategy: retry

Try / catch

TRANSIENT = {"timeout", "unreachable", "upstream_error"}
for attempt in range(4):
    resp = await client.get(f"{proxy}/mcp/tools/list", params={"server_id": sid}, headers=headers)
    if resp.status_code != 200:
        tag = resp.json().get("detail", {}).get("error")
        if tag in TRANSIENT and attempt < 3:
            await asyncio.sleep(2 ** attempt)
            continue
    break
resp.raise_for_status()

Prevention

When it happens

Trigger: Upstream MCP server down or DNS failing (unreachable -> 502); upstream read timeout (-> 504); upstream returned 5xx (upstream_error -> 502); upstream requires auth the proxy lacks (auth_required/forbidden -> 401/403); unexpected exception in the gateway itself (internal -> 500).

Common situations: Flaky internal MCP servers; wrong upstream URL; expired upstream API key; upstream behind a broken gateway returning 502s; slow upstreams exceeding the read timeout under load.

Related errors


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