{"record":{"id":"c87a182429f224c0","repo":"BerriAI/litellm","slug":"upstream-oauth-protected-resource-metadata-unavail","errorCode":null,"errorMessage":"Upstream oauth-protected-resource metadata unavailable for MCP server {mcp_server.name!r}","messagePattern":"Upstream oauth-protected-resource metadata unavailable for MCP server (.+?)","errorType":"http","errorClass":"HTTPException","httpStatus":502,"severity":"error","filePath":"litellm/proxy/_experimental/mcp_server/discoverable_endpoints.py","lineNumber":2189,"sourceCode":"                status_code=502,\n                detail=(\n                    f\"Failed to fetch upstream oauth-protected-resource metadata for MCP server {mcp_server.name!r}\"\n                ),\n            )\n\n        if upstream_metadata is not None:\n            if mcp_server.is_true_passthrough or mcp_server.is_oauth_delegate:\n                return upstream_metadata\n            return {**upstream_metadata, \"resource\": resource_url}\n\n        # Upstream responded but with non-200 or non-dict payload. For\n        # pass-through servers the gateway is NOT the authorization server,\n        # so we must not fall through to the default gateway metadata —\n        # that would point clients at the wrong IdP.\n        verbose_logger.warning(\n            \"Upstream oauth-protected-resource metadata unavailable for pass-through MCP server %r\", mcp_server.name\n        )\n        raise HTTPException(\n            status_code=502,\n            detail=(f\"Upstream oauth-protected-resource metadata unavailable for MCP server {mcp_server.name!r}\"),\n        )\n\n    obo_response: Final = _obo_protected_resource_response(mcp_server, resource_url)\n    if obo_response is not None:\n        return obo_response\n\n    # An OBO server with no configured issuer falls through to the gateway default so discovery still\n    # returns metadata; every other non-oauth2 named server 404s to avoid enumeration.\n    if mcp_server is None or mcp_server.auth_type != MCPAuth.oauth2_token_exchange:\n        _raise_unless_oauth2_discovery_server(mcp_server, mcp_server_name, \"not an OAuth-protected resource\")\n\n    if explicitly_named and mcp_server is not None and mcp_server.is_gateway_managed_oauth2:\n        return {\n            \"authorization_servers\": [f\"{request_base_url}/mcp\"],\n            \"resource\": resource_url,\n            \"scopes_supported\": (mcp_server.scopes if mcp_server.scopes else []),","sourceCodeStart":2171,"sourceCodeEnd":2207,"githubUrl":"https://github.com/BerriAI/litellm/blob/77b7c6c40c0c5aa5fbcb1d6a1825ac39ca8829b8/litellm/proxy/_experimental/mcp_server/discoverable_endpoints.py#L2171-L2207","documentation":"Raised when fetching the upstream RFC 9728 oauth-protected-resource metadata for an MCP server failed (network error, non-200, or unusable payload), so the 401 challenge cannot be built from upstream data.","triggerScenarios":"Thrown at litellm/proxy/_experimental/mcp_server/discoverable_endpoints.py:2189 when the library encounters an invalid state.","commonSituations":"See trigger scenarios.","solutions":["Retry later; verify the upstream server publishes protected-resource metadata."],"exampleFix":"Check upstream availability and metadata endpoint.","handlingStrategy":"try-catch","validationCode":null,"typeGuard":null,"tryCatchPattern":null,"preventionTips":[],"tags":[],"backgroundTag":null,"analyzedSha":"77b7c6c40c0c5aa5fbcb1d6a1825ac39ca8829b8","analyzedAt":"2026-08-18T11:44:31.656Z","contentChangedAt":null,"schemaVersion":2},"datasetVersion":"2026-09-14T05:17:10.506Z"}