Kuberwastaken/claurst · error · anyhow::Error

exchange_code: request failed

Error message

exchange_code: request failed: {}

What it means

The HTTP POST to the OAuth token_endpoint (authorization-code grant with PKCE verifier) failed at the transport level — connection refused, DNS failure, TLS error, or timeout. The endpoint URL comes from the server's protected-resource metadata; no HTTP response was received.

Solutions

  1. Verify network connectivity and the token endpoint URL from the server's OAuth metadata
  2. Check TLS/proxy configuration for the authorization server host
  3. Retry the authentication flow after resolving the network issue
Defensive patterns

Strategy: retry

When it happens

Trigger: Thrown at src-rust/crates/mcp/src/oauth.rs:486 when the library encounters an invalid state.

Common situations: See trigger scenarios.


AI-assisted analysis of Kuberwastaken/claurst@b0637c97ec (2026-09-10). Data as JSON: /api/errors/55af0a08cb9f0e7e. Report an issue: GitHub.

Appendix: source

Thrown at src-rust/crates/mcp/src/oauth.rs:486

    token_endpoint: &str,
    code: &str,
    verifier: &str,
    redirect_uri: &str,
) -> anyhow::Result<McpToken> {
    let client = reqwest::Client::new();
    let params = [
        ("grant_type", "authorization_code"),
        ("code", code),
        ("code_verifier", verifier),
        ("redirect_uri", redirect_uri),
    ];

    let resp = client
        .post(token_endpoint)
        .form(&params)
        .send()
        .await
        .map_err(|e| anyhow::anyhow!("exchange_code: request failed: {}", e))?;

    if !resp.status().is_success() {
        let status = resp.status();
        let body = resp.text().await.unwrap_or_default();
        anyhow::bail!("exchange_code: HTTP {} — {}", status, body);
    }

    #[derive(serde::Deserialize)]
    struct TokenResponse {
        access_token: String,
        refresh_token: Option<String>,
        expires_in: Option<u64>,
        scope: Option<String>,
    }

    let tr: TokenResponse = resp.json().await.map_err(|e| anyhow::anyhow!("exchange_code: bad JSON: {}", e))?;

    let expires_at = tr.expires_in.map(|secs| {

View on GitHub (pinned to b0637c97ec)