Hmbown/CodeWhale · error
OIDC discovery returned unsupported
Error message
OIDC discovery returned unsupported {field} scheme What it means
One of the OAuth endpoints advertised by the discovery document uses a URL scheme other than http or https (e.g. a javascript: or custom-scheme URL). Such an endpoint can never be a valid OAuth endpoint, so discovery validation rejects it before any token exchange is attempted.
Solutions
- Inspect the provider's discovery document and check the {field} value's scheme.
- Fix the provider configuration so the endpoint is a proper https URL.
- If you operate the IdP, correct or regenerate its well-known document.
- Switch to documented-path endpoints instead of discovery if the provider cannot be fixed.
Example fix
// before "device_authorization_endpoint": "myapp://device" // unsupported scheme // after "device_authorization_endpoint": "https://auth.example.com/device"
Defensive patterns
Strategy: validation
Validate before calling
if let Ok(url) = reqwest::Url::parse(endpoint) {
if !matches!(url.scheme(), "http" | "https") {
eprintln!("endpoint scheme {scheme} is not usable for OAuth", scheme = url.scheme());
}
} Type guard
fn is_http_url(s: &str) -> bool {
reqwest::Url::parse(s).map(|u| matches!(u.scheme(), "http" | "https")).unwrap_or(false)
} Prevention
- Only point discovery at IdPs that advertise proper https:// endpoint URLs.
- Sanity-check a self-hosted provider's well-known document after every IdP upgrade.
- Treat non-http(s) endpoints in a discovery document as a sign of a malicious or broken provider.
- Prefer providers with a known, audited discovery implementation.
When it happens
Trigger: validate_discovered_oauth_endpoint parsing a non-empty {field} endpoint (device authorization, token, etc.) whose reqwest::Url scheme() is not "http" or "https".
Common situations: Misbehaving or malicious identity provider returning garbage or non-HTTP endpoint URLs; a discovery document field pointing at an app-specific custom scheme; typos in a self-hosted provider's static discovery doc.
Understand the failure class
Background: "Invalid URL" errors: why new URL(), URI.parse, and reqwest::Url reject your string — missing scheme, whitespace, and bad path format — this error's family across 39 libraries.
Related errors
- OIDC discovery issuer does not match the requested issuer
- OIDC discovery returned credentials in
- OIDC discovery returned
- returned a verification URI with embedded credentials
- returned an untrusted verification URI
AI-assisted analysis of Hmbown/CodeWhale@73e0f67d83 (2026-09-22).
Data as JSON: /api/errors/afab4690d4602a80.
Report an issue: GitHub.
Appendix: source
Thrown at crates/tui/src/oauth.rs:690
Ok(())
}
/// Validate one discovered endpoint against the issuer: https-or-http scheme,
/// no plaintext downgrade, no embedded credentials, same origin.
fn validate_discovered_oauth_endpoint(
endpoint: Option<String>,
field: &str,
issuer: &str,
) -> Result<String> {
let endpoint = endpoint
.as_deref()
.map(str::trim)
.filter(|endpoint| !endpoint.is_empty())
.with_context(|| format!("OIDC discovery missing {field}"))?;
let parsed = reqwest::Url::parse(endpoint)
.with_context(|| format!("OIDC discovery returned an invalid {field}"))?;
if !matches!(parsed.scheme(), "http" | "https") {
bail!("OIDC discovery returned unsupported {field} scheme");
}
let issuer = oauth_endpoint_url(issuer).context("OIDC issuer is not a trusted URL")?;
if issuer.scheme() == "https" && parsed.scheme() != "https" {
bail!("OIDC discovery attempted to downgrade {field} from HTTPS");
}
if !parsed.username().is_empty() || parsed.password().is_some() {
bail!("OIDC discovery returned credentials in {field}");
}
if parsed.origin() != issuer.origin() {
bail!("OIDC discovery returned {field} on a different origin than the issuer");
}
let _ = oauth_endpoint_url(parsed.as_str())?;
Ok(endpoint.to_string())
}
/// Documented-path endpoints for a provider row, no discovery.
fn fallback_oauth_endpoints(params: &OAuthProviderParams, issuer: &str) -> OAuthEndpoints {
OAuthEndpoints {View on GitHub (pinned to 73e0f67d83)