FasterXML/jackson-databind · error · IllegalArgumentException
Unsuitable method ( ) decorated with @JsonCreator (for Enum…
Error message
Unsuitable method ({}) decorated with @JsonCreator (for Enum type {}) What it means
Thrown by BasicDeserializerFactory when an enum type has a static factory method annotated @JsonCreator that Jackson wants to use for key (EnumMap/Enum key) deserialization, but the method signature is unsuitable. For the key-deserializer path, the factory must take exactly one parameter of type String and return a type assignable to the enum class; otherwise this error is raised.
Solutions
- Ensure the @JsonCreator static factory used for enum key deserialization takes a single String argument and returns the enum type.
- If the method is meant for value (not key) deserialization, move/annotate a separate String-arg factory, or remove @JsonCreator from the unsuitable method.
- Use @JsonCreator(mode=Mode.DELEGATING) on a single-arg delegating constructor/factory with a String-compatible type.
Example fix
// before: int parameter -> unsuitable for enum key deser
public enum Code {
@JsonCreator public static Code fromCode(int v){...}
}
// after: separate String-arg factory for key deser
public enum Code {
@JsonCreator public static Code fromKey(String name){...}
} Defensive patterns
Strategy: validation
Validate before calling
// Validate the enum's @JsonCreator factory: single String param, return type assignable to enum.
for (Method m : enumClass.getMethods()) {
if (m.isAnnotationPresent(JsonCreator.class)
&& Modifier.isStatic(m.getModifiers())
&& (m.getParameterCount() != 1 || m.getParameterTypes()[0] != String.class
|| !enumClass.isAssignableFrom(m.getReturnType()))) {
throw new IllegalStateException("Unsuitable enum creator: " + m);
}
} Type guard
boolean isEnumKeyFactory(Method m, Class<? extends Enum> enumClass) {
return Modifier.isStatic(m.getModifiers())
&& m.getParameterCount() == 1
&& m.getParameterTypes()[0] == String.class
&& enumClass.isAssignableFrom(m.getReturnType());
} Prevention
- Keep enum @JsonCreator factories to a single String argument returning the enum.
- Annotate value-deserialization creators separately from key-deserialization ones.
- Test enum key deserialization (EnumMap/Map<Enum,?>) in unit tests.
When it happens
Trigger: An enum declares @JsonCreator on a static method that has zero/multiple parameters, a non-String parameter, or a return type that is not compatible with the enum class, and Jackson attempts to build an enum key deserializer that would use it.
Common situations: Annotating a generic fromJson(Map)/fromJson(int) factory with @JsonCreator expecting it to be used for enum keys; sharing a creator between value and key deserialization where only a String-arg factory is valid; refactor that changed the parameter type.
Related errors
- _anySetter already set to non-null
- Cannot construct EnumMap; generic (key) type not available
- Duplicate property ' ' for
- Invalid Object Id definition for
- AnnotationIntrospector returned `Class<
AI-assisted analysis of FasterXML/jackson-databind@87876ca5c0 (2026-08-11).
Data as JSON: /api/errors/71834f94d6b5e692.
Report an issue: GitHub.
Appendix: source
Thrown at src/main/java/tools/jackson/databind/deser/BasicDeserializerFactory.java:1283
Class<?> returnType = factory.getRawReturnType();
// usually should be class, but may be just plain Enum<?> (for Enum.valueOf()?)
if (returnType.isAssignableFrom(enumClass)) {
// note: mostly copied from 'EnumDeserializer.deserializerForCreator(...)'
if (factory.getRawParameterType(0) != String.class) {
// [databind#2725]: Should not error out because (1) there may be good creator
// method and (2) this method may be valid for "regular" enum value deserialization
// (leaving aside potential for multiple conflicting creators)
// throw new IllegalArgumentException("Parameter #0 type for factory method ("+factory+") not suitable, must be java.lang.String");
continue;
}
if (config.canOverrideAccessModifiers()) {
ClassUtil.checkAndFixAccess(factory.getMember(),
ctxt.isEnabled(MapperFeature.OVERRIDE_PUBLIC_ACCESS_MODIFIERS));
}
return JDKKeyDeserializers.constructEnumKeyDeserializer(enumRes, factory, byEnumNamingResolver, byToStringResolver, byIndexResolver);
}
}
throw new IllegalArgumentException("Unsuitable method ("+factory+") decorated with @JsonCreator (for Enum type "
+enumClass.getName()+")");
}
}
// Also, need to consider @JsonValue, if one found
return JDKKeyDeserializers.constructEnumKeyDeserializer(enumRes, byEnumNamingResolver, byToStringResolver, byIndexResolver);
}
/*
/**********************************************************************
/* DeserializerFactory impl: find explicitly supported types
/**********************************************************************
*/
/**
* Method that can be used to check if databind module has deserializer
* for given (likely JDK) type: explicit meaning that it is not automatically
* generated for POJO.
*<p>View on GitHub (pinned to 87876ca5c0)