xai-org/grok-build · error · OidcError

OidcError::DiscoveryHttp

Error message

OidcError::DiscoveryHttp

What it means

OidcError::DiscoveryHttp is raised during OIDC discovery when the issuer's well-known document endpoint returns a non-success HTTP status. It carries the numeric status and the discovery URL that was requested. This means the IdP metadata could not be fetched, so no OIDC flow can proceed.

Source

Thrown at crates/codegen/xai-grok-shell/src/auth/oidc/protocol.rs:317

    backon::ExponentialBuilder::default()
        .with_max_times(2)
        .with_min_delay(StdDuration::from_millis(500))
        .with_max_delay(StdDuration::from_secs(2))
        .with_jitter()
}
async fn discover_once(issuer_key: &str) -> anyhow::Result<Discovery> {
    let url = format!("{issuer_key}/.well-known/openid-configuration");
    tracing::debug!(url = %url, "OIDC: fetching discovery document");
    let resp = with_alpha_test_key(
        crate::http::shared_client()
            .get(&url)
            .timeout(StdDuration::from_secs(10)),
        &url,
    )
    .send()
    .await?;
    if !resp.status().is_success() {
        return Err(anyhow::Error::new(OidcError::DiscoveryHttp {
            status: resp.status().as_u16(),
            url,
        }));
    }
    let doc: Discovery = resp.json().await?;
    tracing::debug!(
        authorization_endpoint = %doc.authorization_endpoint,
        token_endpoint = %doc.token_endpoint,
        jwks_uri = ?doc.jwks_uri,
        id_token_algs = ?doc.id_token_signing_alg_values_supported,
        "OIDC: discovery complete"
    );
    Ok(doc)
}
#[cfg(test)]
pub(super) fn clear_discovery_cache() {
    DISCOVERY_CACHE.write().clear();
}

View on GitHub (pinned to bc7f02eddd)

Solutions

  1. Check the status and URL in the error: open the URL in a browser/curl and confirm it returns JSON
  2. Fix the issuer URL in your OIDC config (must be the base issuer, not the full well-known path)
  3. Verify network/proxy access from the machine running the shell; retry if the IdP is temporarily down

Example fix

// before
issuer = "https://idp.example.com/.well-known/openid-configuration"
// after
issuer = "https://idp.example.com"  // discovery path is appended automatically
Defensive patterns

Strategy: retry

Validate before calling

// preflight: verify discovery is reachable before the flow
async fn discovery_ok(issuer: &str) -> bool {
    let url = format!("{}/.well-known/openid-configuration", issuer.trim_end_matches('/'));
    reqwest::get(&url).await.map(|r| r.status().is_success()).unwrap_or(false)
}

Try / catch

match discover(&cfg).await {
    Err(e) if matches!(e.downcast_ref::<OidcError>(), Some(OidcError::DiscoveryHttp { status, .. })) => {
        eprintln!("Discovery HTTP failure, retrying once...");
        tokio::time::sleep(Duration::from_secs(2)).await;
        discover(&cfg).await
    }
    other => other,
}

Prevention

When it happens

Trigger: discover() issues a GET (10s timeout) to `<issuer>/.well-known/openid-configuration`; resp.status().is_success() is false, producing DiscoveryHttp { status, url }.

Common situations: Wrong issuer URL in config (typo or trailing wrong path), IdP temporarily down, corporate proxy/gateway returning 403/502, discovery path not exposed by a non-standard provider.

Related errors


AI-assisted analysis of xai-org/grok-build@bc7f02eddd (2026-08-31). Data as JSON: /api/errors/70fd656eaf6a6b86. Report an issue: GitHub.