apache/pulsar · error · IllegalArgumentException
Field ${name} must be of type ${type}. Object: ${o} actual t
Error message
Field ${name} must be of type ${type}. Object: ${o} actual type: ${o.getClass()} What it means
Thrown by a simple type validator when a non-null field value is not an instance of the expected type. Null values are allowed (early return), and exact instances return early; anything else fails with the expected type, the object, and its actual runtime class.
Source
Thrown at pulsar-config-validation/src/main/java/org/apache/pulsar/config/validation/ValidatorImpls.java:370
/**
* Validates basic types.
*/
public static class SimpleTypeValidator extends Validator {
private Class<?> type;
public SimpleTypeValidator(Map<String, Object> params) {
this.type = (Class<?>) params.get(ConfigValidationAnnotations.ValidatorParams.TYPE);
}
public static void validateField(String name, Class<?> type, Object o) {
if (o == null) {
return;
}
if (type.isInstance(o)) {
return;
}
throw new IllegalArgumentException(
"Field " + name + " must be of type " + type + ". Object: " + o + " actual type: " + o.getClass());
}
@Override
public void validateField(String name, Object o) {
validateField(name, this.type, o);
}
}
private static Class<?> loadClass(String className) throws ClassNotFoundException {
Class<?> objectClass;
try {
objectClass = Class.forName(className);
} catch (ClassNotFoundException e) {
ClassLoader clsLoader = Thread.currentThread().getContextClassLoader();
if (clsLoader != null) {
objectClass = clsLoader.loadClass(className);
} else {View on GitHub (pinned to 820761864e)
Solutions
- Change the config value so its type matches the declared field type shown in the message.
- Quote values that must stay strings in YAML (e.g. name: "12345") to defeat implicit typing.
- Fix nested structures (map vs list) to match the schema of the config class.
- Convert values programmatically (String.valueOf / Number parsing) before passing them to validation.
Example fix
// before (YAML) — parsed as Integer
maxRedeliverCount: "3"
// after — ensure declared type matches, or explicitly convert in code
int v = Integer.parseInt(o.toString());
validator.validateField("maxRedeliverCount", v); Defensive patterns
Strategy: type-guard
Validate before calling
static <T> boolean isExpectedType(Object o, Class<T> type) {
return o == null || type.isInstance(o);
} Type guard
static <T> T coerce(Object o, Class<T> type) {
if (o == null) return null;
if (type.isInstance(o)) return type.cast(o);
if (type == String.class) return type.cast(String.valueOf(o));
throw new IllegalArgumentException("Expected " + type + " got " + o.getClass());
} Try / catch
try {
validator.validateField("maxRedeliverCount", value);
} catch (IllegalArgumentException e) {
log.error("Config type mismatch: {}", e.getMessage());
throw new ConfigurationException(e.getMessage(), e);
} Prevention
- Quote values in YAML that must remain strings (version: "1.0", id: "0123").
- Be aware YAML/JSON auto-type booleans and numbers (yes/no/on/off, leading zeros).
- Use typed config beans with strict parsers instead of raw Map<String,Object>.
- Run schema validation on config files in CI before deployment.
When it happens
Trigger: A config map (typically Map<String,Object> parsed from YAML/properties) supplies a value of the wrong Java type for a field — e.g. an Integer where a String is required, or a List where a Map is expected — and validateField(name, type, o) is called on it.
Common situations: YAML/JSON auto-typing turning "on"/numbers into booleans/integers; user writes a bare number where a string is expected; nested list/map structure mismatch; age setting given as string vs int after a schema change.
Understand the failure class
Background: Type mismatch errors: IllegalArgumentException, TypeError and type guards across 150 open-source libraries — this error's family across 150 libraries.
Related errors
- Unsupported LongBitmap type: <other.getClass()>
- ${pd}${name} must be a ${cls.getName()}. (${field})
- Field ${name} must be an Iterable but was a ${field.getClass
- Field ${name} must be a Map
- Field '${name}' with value '${o}' does not implement ${class
AI-assisted analysis of apache/pulsar@820761864e (2026-09-06).
Data as JSON: /api/errors/09da1714db7666c6.
Report an issue: GitHub.