googleapis/mcp-toolbox · error
invalid JWT claims format
Error message
invalid JWT claims format
What it means
This error means the JWT was signature-valid, but its claims payload could not be represented as jwt.MapClaims (map[string]any). The generic auth service parses tokens with jwt.Parse and type-asserts token.Claims to MapClaims before validating the audience claim; if the assertion fails the claims are in an unexpected shape and validation aborts. This is a defensive check that rarely fires with well-formed JWTs from compliant issuers.
Source
Thrown at internal/auth/generic/generic.go:242
tokenString := h.Get(a.Name + "_token")
if tokenString == "" {
return nil, nil
}
// Parse and verify the token signature
token, err := jwt.Parse(tokenString, a.kf.Keyfunc)
if err != nil {
return nil, fmt.Errorf("failed to parse and verify JWT token: %w", err)
}
if !token.Valid {
return nil, fmt.Errorf("invalid JWT token")
}
claims, ok := token.Claims.(jwt.MapClaims)
if !ok {
return nil, fmt.Errorf("invalid JWT claims format")
}
// Validate 'aud' (audience) claim
aud, err := claims.GetAudience()
if err != nil {
return nil, fmt.Errorf("could not parse audience from token: %w", err)
}
isAudValid := false
for _, audItem := range aud {
if audItem == a.Audience {
isAudValid = true
break
}
}
if !isAudValid {
return nil, fmt.Errorf("audience validation failed: expected %s, got %v", a.Audience, aud)View on GitHub (pinned to 8cc6e09de2)
Solutions
- Inspect the token payload at jwt.io and confirm claims are a flat JSON object (map), not an array or scalar.
- Ensure the token is issued by your configured authorization server as a standard JWT, not an opaque token.
- If you customized jwt.Parse with a custom claims type, align it with MapClaims or update the auth service accordingly.
Example fix
// before: token with non-object claims payload
Authorization: eyJhbGciOi... (claims: ["not","an","object"])
// after: reissue token with object claims
Authorization: eyJhbGciOi... (claims: {"aud":"my-audience","exp":1893456000}) Defensive patterns
Strategy: type-guard
Validate before calling
parts := strings.Split(tokenString, ".")
if len(parts) != 3 { return fmt.Errorf("not a JWT") }
payload, _ := base64.RawURLEncoding.DecodeString(parts[1])
var claims map[string]any
if err := json.Unmarshal(payload, &claims); err != nil {
return fmt.Errorf("claims are not a JSON object: %w", err)
} Type guard
func isMapClaims(t *jwt.Token) bool {
_, ok := t.Claims.(jwt.MapClaims)
return ok
} Try / catch
claims, err := svc.GetClaimsFromHeader(ctx, header)
if err != nil {
if strings.Contains(err.Error(), "invalid JWT claims format") {
// reject token: non-object claims payload
}
return err
} Prevention
- Decode the token payload at jwt.io before wiring it into clients
- Ensure your IdP issues standard JSON-object claims
- Never hand-craft JWTs with array/scalar payloads
When it happens
Trigger: GetClaimsFromHeader is called with an Authorization-style header '<Name>_token' whose value parses and verifies as a JWT, but token.Claims does not hold a jwt.MapClaims value — e.g. a token parsed into a custom claims struct, or a non-standard claims payload in the token string.
Common situations: Sending a non-JWT opaque string that some parser still marks valid, tokens whose claims are not a JSON object (e.g. a JSON array or string), or a misconfigured JWKS/keyfunc setup where a different parser produced the token object.
Related errors
- no field named %s in claims
- failed to parse and verify JWT token: %w
- invalid JWT token
- could not parse audience from token: %w
- audience validation failed: expected %s, got %v
AI-assisted analysis of googleapis/mcp-toolbox@8cc6e09de2 (2026-09-05).
Data as JSON: /api/errors/ef6250a7c0f619df.
Report an issue: GitHub.