hashicorp/nomad · error
failed to retrieve the ID token claims: %v
Error message
failed to retrieve the ID token claims: %v
What it means
Thrown when oidcToken.IDToken().Claims(&idTokenClaims) fails to JSON-decode the ID token payload into map[string]any. This means the token came back but its ID-token claims could not be parsed — typically a malformed or unexpectedly-encoded ID token from the provider.
Source
Thrown at nomad/acl_endpoint.go:2808
}
// Generate a context with a deadline. This is passed to the OIDC provider
// and used when making remote HTTP requests.
ctx, cancel := context.WithDeadline(context.Background(), time.Now().Add(aclOIDCCallbackRequestExpiryTime))
defer cancel()
// Exchange the state and code for an OIDC provider token.
oidcToken, err := oidcProvider.Exchange(ctx, oidcReq, args.State, args.Code)
if err != nil {
return fmt.Errorf("failed to exchange token with provider: %v", err)
}
if !oidcToken.Valid() {
return errors.New("exchanged token is not valid; potentially expired or empty")
}
var idTokenClaims map[string]any
if err := oidcToken.IDToken().Claims(&idTokenClaims); err != nil {
return fmt.Errorf("failed to retrieve the ID token claims: %v", err)
}
var userClaims map[string]any
if !authMethod.Config.OIDCDisableUserInfo {
if userTokenSource := oidcToken.StaticTokenSource(); userTokenSource != nil {
if err := oidcProvider.UserInfo(ctx, userTokenSource, idTokenClaims["sub"].(string), &userClaims); err != nil {
return fmt.Errorf("failed to retrieve the user info claims: %v", err)
}
}
}
// Generate the data used by the go-bexpr selector that is an internal
// representation of the claims that can be understood by Nomad.
oidcInternalClaims, err := auth.SelectorData(authMethod, idTokenClaims, userClaims)
if err != nil {
return err
}
View on GitHub (pinned to 482b49bf1a)
Solutions
- Inspect the raw ID token (jwt.io) returned by the provider for a non-standard claims payload.
- Upgrade Nomad / the cap library — parsing bugs are fixed upstream.
- Check for a reverse proxy or security appliance mangling the token response body.
- Switch to a standards-compliant provider configuration or open an issue with the provider vendor.
Defensive patterns
Strategy: try-catch
Validate before calling
// decode the ID token client-side first to sanity-check claims
parts := strings.Split(rawIDToken, ".")
if len(parts) != 3 { return errors.New("not a JWT") }
payload, _ := base64.RawURLEncoding.DecodeString(parts[1])
var claims map[string]any
if err := json.Unmarshal(payload, &claims); err != nil { return err }
if _, ok := claims["sub"]; !ok { return errors.New("missing sub") } Try / catch
if err := oidcToken.IDToken().Claims(&idTokenClaims); err != nil {
return fmt.Errorf("failed to retrieve the ID token claims: %v", err)
} Prevention
- Prefer well-known, standards-compliant IdPs.
- Inspect raw tokens with a JWT decoder when introducing a new provider.
- Keep Nomad and its cap dependency updated for parser fixes.
When it happens
Trigger: OIDCCompleteAuth calls IDToken().Claims() on the token returned by Exchange and the cap library returns a decode error (malformed JWT payload, non-object claims).
Common situations: Misbehaving or non-standard IdP returning an ID token whose claims are not a JSON object, corrupted token from a proxy, provider returning an opaque token where an ID token is expected.
Related errors
- no auth method config or client assertion
- missing Audience
- PrivateKey is required for `private_key` KeySource
- invalid KeyIDHeader
- failed to retrieve the user info claims: %v
AI-assisted analysis of hashicorp/nomad@482b49bf1a (2026-09-04).
Data as JSON: /api/errors/381c3a2ba85c0487.
Report an issue: GitHub.