Skip to content

OAuth discovery aborts after first malformed well-known URL candidate #544

@sorech

Description

@sorech

Describe the bug
When the RMCP client performs OAuth metadata discovery, it stops immediately if the first candidate /.well-known/oauth-authorization-server URL returns non-JSON content (e.g., an HTML login page). The JSON parse error is treated as fatal, so the client never tries the rest of the RFC 8414 fallback URLs.

To Reproduce

  1. Register a streamable MCP server whose default well-known URL (e.g., https://example.com/.well-known/oauth-authorization-server/) returns HTML instead of JSON, but whose canonical fallback https://example.com/.well-known/oauth-authorization-server returns valid metadata.
  2. Run codex mcp add --url https://example.com/mcp/default server-name with experimental_use_rmcp_client = true.
  3. Observe that Codex reports Failed to parse metadata and bails out without attempting the fallback URL.

Expected behavior
If a candidate well-known URL returns malformed JSON, the RMCP client should log the failure and continue trying the next fallback URL (per RFC 8414), eventually succeeding when it reaches the canonical JSON endpoint.

Logs
Added global MCP server 'server-name'.
Detected OAuth support. Starting OAuth flow…
Error: Metadata error: Failed to parse metadata: error decoding response body

Additional context
Minimal fix: treat parse failures as “no metadata here” so the loop keeps going:

match self.fetch_authorization_metadata(&discovery_url).await {
Ok(Some(metadata)) => return Ok(Some(metadata)),
Ok(None) => continue,
Err(_) => continue, // <— new branch with swallow parse errors, try next candidate
}

Alternatively, inside fetch_authorization_metadata, convert JSON parse errors into Ok(None) after logging the body.
Either approach lets discovery fall through to the next candidate URL.

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions