apache/pulsar · error · IllegalArgumentException

${pd}${name} must be a ${cls.getName()}. (${field})

Error message

${pd}${name} must be a ${cls.getName()}. (${field})

What it means

The scalar NestableFieldValidator throws IllegalArgumentException when the field is non-null but is not an instance of the expected class (cls.isInstance(field) fails). The message includes the field descriptor prefix, name, expected class, and the offending value.

Source

Thrown at pulsar-config-validation/src/main/java/org/apache/pulsar/config/validation/ConfigValidationUtils.java:47

     *
     * @param cls     the Class the field should be a type of
     * @param notNull whether or not a value of null is valid
     * @return a NestableFieldValidator for that class
     */
    public static NestableFieldValidator fv(final Class<?> cls, final boolean notNull) {
        return new NestableFieldValidator() {
            @Override
            public void validateField(String pd, String name, Object field)
                    throws IllegalArgumentException {
                if (field == null) {
                    if (notNull) {
                        throw new IllegalArgumentException("Field " + name + " must not be null");
                    } else {
                        return;
                    }
                }
                if (!cls.isInstance(field)) {
                    throw new IllegalArgumentException(
                            pd + name + " must be a " + cls.getName() + ". (" + field + ")");
                }
            }
        };
    }

    /**
     * Returns a new NestableFieldValidator for a List of the given Class.
     *
     * @param cls     the Class of elements composing the list
     * @param notNull whether or not a value of null is valid
     * @return a NestableFieldValidator for a list of the given class
     */
    public static NestableFieldValidator listFv(Class<?> cls, boolean notNull) {
        return listFv(fv(cls, notNull), notNull);
    }

    /**

View on GitHub (pinned to 820761864e)

Solutions

  1. Correct the value's type in the config file (remove quotes around numbers/booleans in JSON/YAML)
  2. If set programmatically, assign the declared field type (Integer, Long, boolean, etc.) exactly
  3. Check the config class field declaration to see the expected class named in the message

Example fix

// before (YAML)
port: "6650"
// after
port: 6650
Defensive patterns

Strategy: validation

Validate before calling

// before validateConfig: coerce common string->number cases
Object port = conf.get("port");
if (port instanceof String) conf.put("port", Integer.valueOf((String) port));

Type guard

static <T> boolean isInstance(T expected, Object o) { return expected != null && expected.getClass().isInstance(o); }

Try / catch

try {
    ConfigValidation.validateConfig(conf);
} catch (IllegalArgumentException e) {
    throw new IllegalStateException("Config type error (check quoting/units): " + e.getMessage(), e);
}

Prevention

When it happens

Trigger: A config property is parsed/set with the wrong Java type — e.g. a String where an Integer/long is expected, a String 'true' where a boolean is expected — then passed through validateField during ConfigValidation.validateConfig.

Common situations: Typo'd values in broker.conf (a port given as 'http://...' instead of a number); a JSON/YAML config where numbers were quoted as strings; programmatic construction of a config object with wrong types.

Related errors


AI-assisted analysis of apache/pulsar@820761864e (2026-09-06). Data as JSON: /api/errors/4427e3d334dd0cdc. Report an issue: GitHub.