{"record":{"id":"0842668fa6a36084","repo":"zed-industries/zed","slug":"could-not-fetch-authorization-server-metadata-for","errorCode":null,"errorMessage":"Could not fetch Authorization Server Metadata for {}","messagePattern":"Could not fetch Authorization Server Metadata for (.+?)","errorType":"exception","errorClass":null,"httpStatus":null,"severity":"error","filePath":"crates/context_server/src/oauth.rs","lineNumber":847,"sourceCode":"                        .ok_or_else(|| anyhow!(\"missing authorization_endpoint\"))?,\n                    token_endpoint: response\n                        .token_endpoint\n                        .ok_or_else(|| anyhow!(\"missing token_endpoint\"))?,\n                    registration_endpoint: response.registration_endpoint,\n                    scopes_supported: response.scopes_supported,\n                    code_challenge_methods_supported: response.code_challenge_methods_supported,\n                    client_id_metadata_document_supported: response\n                        .client_id_metadata_document_supported\n                        .unwrap_or(false),\n                });\n            }\n            Err(err) => {\n                log::debug!(\"Failed to fetch Auth Server Metadata from {}: {}\", url, err);\n            }\n        }\n    }\n\n    bail!(\n        \"Could not fetch Authorization Server Metadata for {}\",\n        issuer\n    )\n}\n\n/// Run the full discovery flow: fetch resource metadata, then auth server\n/// metadata, then select scopes. Client registration is resolved separately,\n/// once the real redirect URI is known.\npub async fn discover(\n    http_client: &Arc<dyn HttpClient>,\n    server_url: &Url,\n    www_authenticate: &WwwAuthenticate,\n) -> Result<OAuthDiscovery> {\n    let resource_metadata =\n        fetch_protected_resource_metadata(http_client, server_url, www_authenticate).await?;\n\n    let auth_server_url = resource_metadata\n        .authorization_servers","sourceCodeStart":829,"sourceCodeEnd":865,"githubUrl":"https://github.com/zed-industries/zed/blob/f4178619acd0d47ea1f76a2025c42962c6d6638c/crates/context_server/src/oauth.rs#L829-L865","documentation":"Discovery failed at the second stage: none of the Authorization Server Metadata candidate URLs (RFC 8414 /oauth-authorization-server well-known and OIDC Discovery /.well-known/openid-configuration, in MCP-spec priority order) could be fetched successfully. As with error 167, each individual failure is only logged at debug level and the final bail names just the issuer, so the root cause (DNS, TLS, 404, non-JSON, or an issuer-mismatch bail swallowed by the loop) requires debug logs to see. Note that a candidate can 'fail' via the issuer-mismatch bail in the Ok arm, which is caught by this same loop and retried on the next candidate before giving up.","triggerScenarios":"fetch_auth_server_metadata() iterates auth_server_metadata_urls(issuer); every fetch_json call returns Err — connection refused, 404 for both endpoint styles, HTML instead of JSON, or the Ok branch bailing on issuer mismatch for each candidate.","commonSituations":"Authorization server that is a plain OAuth2 server without OIDC discovery and without RFC 8414 endpoints; auth server behind auth-offloading proxy that returns an HTML login page on the well-known path; wrong issuer listed in authorization_servers (points at resource not auth server); network egress blocked to the auth domain.","solutions":["Verify the auth server serves metadata at either /.well-known/oauth-authorization-server or /.well-known/openid-configuration for the exact issuer path (curl both)","Correct the authorization_servers entry in the Protected Resource Metadata so it names the real authorization server issuer","Ensure the endpoint returns JSON with 200 and no auth wall; allowlist it in the proxy/SSO layer","Turn on debug logging to see each candidate URL and its specific error before changing configuration"],"exampleFix":"# before: issuer points at the resource, auth metadata 404s\n\"authorization_servers\": [\"https://mcp.example.com\"]\n\n# after: issuer points at the actual authorization server\n\"authorization_servers\": [\"https://auth.example.com\"]\n# where https://auth.example.com/.well-known/openid-configuration returns 200 JSON","handlingStrategy":"try-catch","validationCode":"// preflight both discovery endpoint styles for the issuer\nasync fn as_metadata_reachable(http: &Arc<dyn HttpClient>, issuer: &Url) -> bool {\n    auth_server_metadata_urls(issuer).iter().any(|u| {\n        fetch_json::<serde_json::Value>(http, u).await.is_ok()\n    })\n}","typeGuard":null,"tryCatchPattern":"match fetch_auth_server_metadata(&client, &issuer).await {\n    Ok(meta) => Ok(meta),\n    Err(err) if err.to_string().contains(\"Could not fetch Authorization Server Metadata\") => {\n        // candidates: /oauth-authorization-server and /openid-configuration; curl them to see which failed and why\n        if is_transient_network(&err) { retry_with_backoff().await } else { Err(err) }\n    }\n    Err(err) => Err(err),\n}","preventionTips":["Confirm the auth server exposes RFC 8414 or OIDC discovery for the exact issuer path before advertising it in authorization_servers","Make sure the well-known endpoints are unauthenticated and return application/json, not an SSO HTML page","Keep debug logging on during setup: each candidate failure is logged individually before the aggregate bail"],"tags":["oauth","mcp","discovery","network","rfc-8414","openid-configuration"],"backgroundTag":"oauth-discovery-endpoint-unreachable","analyzedSha":"f4178619acd0d47ea1f76a2025c42962c6d6638c","analyzedAt":"2026-08-20T19:29:52.058Z","contentChangedAt":"2026-08-20T19:29:52.058Z","schemaVersion":2},"datasetVersion":"2026-09-14T05:17:10.506Z"}