xai-org/grok-build · error · OidcError
OidcError::IdTokenMissingKid
Error message
OidcError::IdTokenMissingKid
What it means
OidcError::IdTokenMissingKid is raised by validate_and_extract_user_info when the id_token's JOSE header lacks a `kid` (key ID). The library needs `kid` to select the matching JWK from the provider's JWKS for signature verification, so a token without it cannot be validated.
Source
Thrown at crates/codegen/xai-grok-shell/src/auth/oidc/protocol.rs:648
return Err(anyhow::Error::new(
OidcError::AlgNotInDiscoverySupportedList {
alg: alg_name.to_owned(),
},
));
}
Ok(())
}
pub(super) async fn validate_and_extract_user_info(
token: &str,
discovery: &Discovery,
expected_issuer: &str,
expected_client_id: &str,
expected_nonce: &str,
) -> anyhow::Result<OidcUserInfo> {
let header = jsonwebtoken::decode_header(token)?;
let kid = header
.kid
.ok_or_else(|| anyhow::Error::new(OidcError::IdTokenMissingKid))?;
let jwks_uri = discovery
.jwks_uri
.as_ref()
.ok_or_else(|| anyhow::Error::new(OidcError::DiscoveryMissingJwksUri))?;
let jwks: jsonwebtoken::jwk::JwkSet = with_alpha_test_key(
crate::http::shared_client()
.get(jwks_uri)
.timeout(std::time::Duration::from_secs(10)),
jwks_uri,
)
.send()
.await?
.error_for_status()?
.json()
.await?;
let jwk = jwks
.find(&kid)
.ok_or_else(|| anyhow::Error::new(OidcError::JwkNotFound { kid: kid.clone() }))?;View on GitHub (pinned to bc7f02eddd)
Solutions
- Configure the IdP to include the kid header in issued id_tokens (standard behavior for multi-key JWKS providers)
- If the provider uses a single key, it must still set kid to conform to OIDC spec; file/request a provider fix
- Try a different provider/realm that issues spec-compliant tokens
Defensive patterns
Strategy: validation
Validate before calling
// inspect the unverified header first; fail fast with a clearer message
fn header_has_kid(token: &str) -> bool {
jsonwebtoken::decode_header(token).map(|h| h.kid.is_some()).unwrap_or(false)
} Try / catch
match res {
Err(e) if matches!(e.downcast_ref::<OidcError>(), Some(OidcError::IdTokenMissingKid)) => {
eprintln!("Provider omits kid in id_token header; provider must include kid per OIDC spec");
}
other => other?,
} Prevention
- Verify with jwt.io / decode_header that issued tokens carry a kid header
- Prefer mainstream IdPs (Keycloak, Auth0, Okta, Entra) that always set kid
- Reject non-compliant providers during onboarding rather than at login time
When it happens
Trigger: decode_header(token) succeeds but header.kid is None during id_token validation after the token exchange/refresh.
Common situations: Providers that sign with a single static key and omit `kid` in the JWS header; non-standard or homegrown OIDC servers; proxy-rewritten tokens.
Related errors
- OidcError::UnsupportedAlg
- OidcError::AlgNotInDiscoverySupportedList
- OidcError::DiscoveryMissingJwksUri
- OidcError::JwkNotFound
- OidcError::IssuerMismatch
AI-assisted analysis of xai-org/grok-build@bc7f02eddd (2026-08-31).
Data as JSON: /api/errors/3ea3571ee8b15785.
Report an issue: GitHub.