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

  1. Fix the IdP to emit iss as a standard string (per RFC 7519)
  2. Regenerate test tokens with a standard library ensuring string iss
  3. 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

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


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