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
- 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.
- Retry only the transient tags (timeout, unreachable, upstream_error) with backoff.
- 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
- Branch on the body's error tag: only timeout/unreachable/upstream_error are worth retrying; 401/403 need credential fixes.
- Use the aggregate tools/list and read _meta['litellm.ai/server_outcomes'] to degrade gracefully instead of hard-failing.
- Track per-server fault rates to catch chronically unhealthy upstreams early.
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
- Toolset '{toolset_name}' not found
- invalid_request
- Path parameter '{param_name}' must not contain path separato
- Path parameter '{param_name}' cannot include '.' or '..' seg
- OpenAPI spec not found at {filepath}
AI-assisted analysis of BerriAI/litellm@77b7c6c40c (2026-08-18).
Data as JSON: /api/errors/d98705ac1cf9314b.
Report an issue: GitHub.