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

  1. Read %T in the error to identify the actual claim type
  2. Point the claim mapping at a scalar leaf using a JSON pointer, e.g. /resource_access/myclient/roles/0
  3. Use ListClaimMappings instead of ClaimMappings if the claim is an array
  4. 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

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


AI-assisted analysis of hashicorp/nomad@482b49bf1a (2026-09-04). Data as JSON: /api/errors/76f5cbb5d548e923. Report an issue: GitHub.