{"record":{"id":"a36d0bdb9e261ea5","repo":"BerriAI/litellm","slug":"failed-to-fetch-upstream-oauth-protected-resource","errorCode":null,"errorMessage":"Failed to fetch upstream oauth-protected-resource metadata for MCP server {mcp_server.name!r}","messagePattern":"Failed to fetch upstream oauth-protected-resource metadata for MCP server (.+?)","errorType":"http","errorClass":"HTTPException","httpStatus":502,"severity":"error","filePath":"litellm/proxy/_experimental/mcp_server/discoverable_endpoints.py","lineNumber":2170,"sourceCode":"            \"authorization_servers\": [f\"{request_base_url}/{mcp_server_name}\"],\n            \"resource\": resource_url,\n            \"scopes_supported\": (mcp_server.scopes if mcp_server.scopes else []),\n        }\n\n    # Pass-through branch: proxy the upstream's own metadata so discovery\n    # directs the client at the real IdP (Okta, Keycloak, …) instead of us.\n    if mcp_server is not None and (\n        mcp_server.is_oauth_passthrough or mcp_server.is_oauth_delegate or mcp_server.is_true_passthrough\n    ):\n        try:\n            upstream_metadata: Final = await fetch_upstream_oauth_protected_resource(mcp_server)\n        except Exception as exc:\n            verbose_logger.warning(\n                \"Failed to fetch upstream oauth-protected-resource metadata for pass-through MCP server %r: %s\",\n                mcp_server.name,\n                exc,\n            )\n            raise HTTPException(\n                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        )","sourceCodeStart":2152,"sourceCodeEnd":2188,"githubUrl":"https://github.com/BerriAI/litellm/blob/77b7c6c40c0c5aa5fbcb1d6a1825ac39ca8829b8/litellm/proxy/_experimental/mcp_server/discoverable_endpoints.py#L2152-L2188","documentation":"Raised when the pass-through branch of oauth-protected-resource discovery cannot retrieve the upstream IdP's metadata (network or fetch failure). The gateway is not the authorization server in this mode, so it cannot fabricate metadata and surfaces a 502.","triggerScenarios":"Thrown at litellm/proxy/_experimental/mcp_server/discoverable_endpoints.py:2170 when the library encounters an invalid state.","commonSituations":"See trigger scenarios.","solutions":["Check connectivity to the upstream server's oauth-protected-resource metadata URL.","Verify the upstream server is reachable and returns valid metadata."],"exampleFix":"curl the .well-known/oauth-protected-resource URL.","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"}