hashicorp/nomad · error
error converting claim '%s' to string from unknown type %T
Error message
error converting claim '%s' to string from unknown type %T
What it means
extractMappings found a configured ClaimMappings source claim whose value exists but has a Go type stringifyClaimValue cannot convert (e.g. map[string]interface{}, nested object). Login's claim extraction fails and the auth request errors out.
Source
Thrown at lib/auth/claims.go:77
Value: values,
List: list,
}, nil
}
// extractMappings extracts the string value mappings.
func extractMappings(
all map[string]interface{}, mapping map[string]string) (map[string]string, error) {
result := make(map[string]string)
for source, target := range mapping {
rawValue := getClaim(all, source)
if rawValue == nil {
continue
}
strValue, ok := stringifyClaimValue(rawValue)
if !ok {
return nil, fmt.Errorf("error converting claim '%s' to string from unknown type %T",
source, rawValue)
}
result[target] = strValue
}
return result, nil
}
// extractListMappings builds a metadata map of string list values from a set
// of claims and claims mappings. The referenced claims must be strings and
// the claims mappings must be of the structure:
//
// {
// "/some/claim/pointer": "metadata_key1",
// "another_claim": "metadata_key2",
// ...
// }View on GitHub (pinned to 482b49bf1a)
Solutions
- Read %T in the error to identify the actual claim type
- Point the claim mapping at a scalar leaf using a JSON pointer, e.g. /resource_access/myclient/roles/0
- Use ListClaimMappings instead of ClaimMappings if the claim is an array
- Ask the IdP admin to expose the value as a scalar claim
Example fix
// before
ClaimMappings: {"/resource_access": "roles"}
// after
ListClaimMappings: {"/resource_access/myclient/roles": "roles"} Defensive patterns
Strategy: type-guard
Validate before calling
// verify claim shape before login by decoding the JWT payload
func claimIsScalar(claims map[string]interface{}, key string) bool {
v := claims[key]
switch v.(type) {
case nil, string, bool, float64, []interface{}:
return true
default:
return false // maps/objects will fail stringification
}
} Type guard
func asScalarClaim(v interface{}) (string, bool) {
switch t := v.(type) {
case string:
return t, true
case bool:
return strconv.FormatBool(t), true
case float64:
return strconv.FormatInt(int64(t), 10), true
default:
return "", false
}
} Try / catch
if err != nil && strings.Contains(err.Error(), "to string from unknown type") {
return fmt.Errorf("claim mapping targets a non-scalar claim: %w", err)
} Prevention
- Point ClaimMappings at scalar leaf claims using JSON pointers, never at objects
- Decode a sample token and confirm each mapped claim's JSON type
- Prefer ListClaimMappings for arrays and objects
When it happens
Trigger: An auth method's ClaimMappings points at a claim (via JSON pointer or key) whose runtime value is a map or other unsupported type — e.g. mapping "resource_access" or an OIDC object claim to a string metadata key.
Common situations: Keycloak-style nested claims (resource_access.client.roles); IdP changed a claim from string to object after an upgrade; %T in the message reveals map[string]interface {} — a strong hint the pointer targets an object, not a leaf.
Related errors
- %q list claim could not be converted to string list
- value %v in %q list claim could not be parsed as string
- no signed workload identity available
- JWT login returned an empty secret
- JWT login did not return a token
AI-assisted analysis of hashicorp/nomad@482b49bf1a (2026-09-04).
Data as JSON: /api/errors/76f5cbb5d548e923.
Report an issue: GitHub.