hashicorp/nomad · error
unable to read iss property of provided token
Error message
unable to read iss property of provided token
What it means
Fires in JWT validation: the token's iss claim is present but is not a string (e.g. an unexpected type), and since BoundIssuer matching expects a string issuer, the claim cannot be read and login fails.
Source
Thrown at lib/auth/jwt/validator.go:80
validator, err := jwt.NewValidator(keySet)
if err != nil {
return nil, err
}
claims, err := validator.Validate(ctx, token, expected)
if err != nil {
return nil, fmt.Errorf("unable to verify signature of JWT token: %v", err)
}
// validate issuer manually, because we allow users to specify an array
if len(methodConf.BoundIssuer) > 0 {
if _, ok := claims["iss"]; !ok {
return nil, fmt.Errorf(
"auth method specifies BoundIssuers but the provided token does not contain issuer information",
)
}
if iss, ok := claims["iss"].(string); !ok {
return nil, fmt.Errorf("unable to read iss property of provided token")
} else if !slices.Contains(methodConf.BoundIssuer, iss) {
return nil, fmt.Errorf("invalid JWT issuer: %v", claims["iss"])
}
}
return claims, nil
}
func usingStaticKeys(keys []string) (jwt.KeySet, error) {
var parsedKeys []crypto.PublicKey
for _, v := range keys {
key, err := jwt.ParsePublicKeyPEM([]byte(v))
parsedKeys = append(parsedKeys, key)
if err != nil {
return nil, fmt.Errorf("unable to parse public key for JWT auth: %v", err)
}
}
return jwt.NewStaticKeySet(parsedKeys)View on GitHub (pinned to 482b49bf1a)
Solutions
- Fix the IdP to emit iss as a standard string (per RFC 7519)
- Regenerate test tokens with a standard library ensuring string iss
- Validate the token structure with jwt.io or a decoder before configuring the auth method
Example fix
// before (non-standard)
{"iss": 12345}
// after
{"iss": "https://idp.example.com"} Defensive patterns
Strategy: validation
Validate before calling
payload := decodeJWTPayload(rawToken)
if iss, ok := payload["iss"]; ok {
if _, isStr := iss.(string); !isStr {
return errors.New("iss claim must be a string per RFC 7519")
}
} Type guard
func issAsString(claims map[string]interface{}) (string, bool) {
iss, ok := claims["iss"]
if !ok { return "", false }
s, ok := iss.(string)
return s, ok
} Try / catch
if err != nil && strings.Contains(err.Error(), "unable to read iss property") {
return fmt.Errorf("token iss claim is not a string; regenerate token with a standards-compliant library: %w", err)
} Prevention
- Generate tokens only with standard JWT libraries that serialize iss as a string
- Decode test tokens and assert iss is a string before wiring up the auth method
- Fix custom IdP implementations to follow RFC 7519 issuer claim typing
When it happens
Trigger: Login where claims["iss"] is present but fails the .(string) type assertion — a non-standard token with iss as non-string type.
Common situations: Custom/misbehaving IdP emitting iss as a non-string; hand-rolled tokens for testing with numeric iss values.
Related errors
- auth method specifies BoundIssuers but the provided token do
- invalid JWT issuer: %v
- 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/b0fbc7b12df2980c.
Report an issue: GitHub.