FasterXML/jackson-databind · error · IllegalStateException
AnnotationIntrospector returned Class {}; expected Class<Val
Error message
AnnotationIntrospector returned Class {}; expected Class<ValueInstantiator> What it means
Thrown from BasicDeserializerFactory._valueInstantiatorInstance when the introspector returns a Class for the value instantiator, but that Class does not extend ValueInstantiator. Only ValueInstantiator subclasses can be instantiated to drive object creation.
Source
Thrown at src/main/java/tools/jackson/databind/deser/BasicDeserializerFactory.java:294
return null;
}
ValueInstantiator inst;
if (instDef instanceof ValueInstantiator valueInstantiator) {
return valueInstantiator;
}
if (!(instDef instanceof Class)) {
throw new IllegalStateException("AnnotationIntrospector returned key deserializer definition of type "
+instDef.getClass().getName()
+"; expected type KeyDeserializer or Class<KeyDeserializer> instead");
}
Class<?> instClass = (Class<?>)instDef;
if (ClassUtil.isBogusClass(instClass)) {
return null;
}
if (!ValueInstantiator.class.isAssignableFrom(instClass)) {
throw new IllegalStateException("AnnotationIntrospector returned Class "+instClass.getName()
+"; expected Class<ValueInstantiator>");
}
HandlerInstantiator hi = config.getHandlerInstantiator();
if (hi != null) {
inst = hi.valueInstantiatorInstance(config, annotated, instClass);
if (inst != null) {
return inst;
}
}
return (ValueInstantiator) ClassUtil.createInstance(instClass,
config.canOverrideAccessModifiers());
}
/*
/**********************************************************************
/* Creator introspection: new (2.18) helper methods
/**********************************************************************
*/View on GitHub (pinned to a50c7d2a1d)
Solutions
- Make the referenced class extend ValueInstantiator (or ValueInstantiator.Base) and implement createUsingDefault / createFromObjectWith.
- If you did not intend to customize instantiation, remove the @JsonValueInstantiator annotation.
- Verify the class hierarchy before wiring.
Example fix
// before
@JsonValueInstantiator(MyFactory.class) // MyFactory does not extend ValueInstantiator
class MyFactory { Object create(){ ... } }
// after
class MyInstantiator extends ValueInstantiator.Base<MyBean> {
@Override public MyBean createUsingDefault(DeserializationContext ctxt){ return new MyBean(); }
}
@JsonValueInstantiator(MyInstantiator.class) Defensive patterns
Strategy: type-guard
Type guard
static boolean isInstantiatorClass(Class<?> c) {
return c != null && ValueInstantiator.class.isAssignableFrom(c);
} Prevention
- Verify the @JsonValueInstantiator target extends ValueInstantiator before deploying.
- Base custom instantiators on ValueInstantiator.Base to get sensible defaults.
- Don't confuse ValueInstantiator with ValueDeserializer.
When it happens
Trigger: @JsonValueInstantiator(MyClass.class) where MyClass does not extend ValueInstantiator, or a custom introspector returning a non-instantiator Class for value-instantiator resolution.
Common situations: Pointing @JsonValueInstantiator at a factory, builder, or plain class by mistake; a refactor that changed a class hierarchy without updating the annotation; confusing ValueInstantiator with ValueDeserializer.
Related errors
- AnnotationIntrospector returned `Class<{}>`; expected `Class
- AnnotationIntrospector returned key deserializer definition
- AnnotationIntrospector returned `Class<{}>`; expected `Class
- AnnotationIntrospector returned Class {}; expected Class<Key
- AnnotationIntrospector returned Converter definition of type
AI-assisted analysis of FasterXML/jackson-databind@a50c7d2a1d (2026-08-06).
Data as JSON: /api/errors/7465f716b2620776.
Report an issue: GitHub.