FasterXML/jackson-databind · error · IllegalArgumentException
Multiple suitable annotated Creator factory methods to be us
Error message
Multiple suitable annotated Creator factory methods to be used as the Key deserializer for type ${rawKeyType} What it means
Thrown by JDKKeyDeserializers._findExplicitStringFactoryMethod when more than one factory method on a class is annotated as a suitable @JsonCreator for key deserialization. The method scans candidate factory methods (that accept a single String parameter) and expects exactly one match; finding a second annotated match is ambiguous and throws IllegalArgumentException. This is a bean-definition error for types used as Map keys.
Source
Thrown at src/main/java/tools/jackson/databind/deser/jdk/JDKKeyDeserializers.java:201
}
return null;
}
private static AnnotatedMethod _findExplicitStringFactoryMethod(DeserializationContext ctxt,
List<AnnotatedAndMetadata<AnnotatedMethod, JsonCreator.Mode>> candidates)
throws JacksonException
{
AnnotatedMethod match = null;
for (AnnotatedAndMetadata<AnnotatedMethod, JsonCreator.Mode> entry : candidates) {
// Note: caller has filtered out invalid candidates; all we need to check are dups
if (entry.metadata != null) {
if (match == null) {
match = entry.annotated;
} else {
// 15-Jun-2021, tatu: Not optimal type or information, but has to do for now
// since we do not get DeserializationContext
Class<?> rawKeyType = entry.annotated.getDeclaringClass();
throw new IllegalArgumentException(
"Multiple suitable annotated Creator factory methods to be used as the Key deserializer for type "
+ClassUtil.nameOf(rawKeyType));
}
}
}
return match;
}
/*
/**********************************************************************
/* KeyDeserializers implementation
/**********************************************************************
*/
@Override
public KeyDeserializer findKeyDeserializer(JavaType type,
DeserializationConfig config, BeanDescription.Supplier beanDescRef)
{View on GitHub (pinned to a50c7d2a1d)
Solutions
- Ensure only one factory method on the key type is annotated as a creator (@JsonCreator).
- If the type has both valueOf and fromString, annotate only one — Jackson will auto-detect the other if needed.
- Remove redundant @JsonCreator annotations from secondary factory methods.
- Use a custom KeyDeserializer via SimpleModule.addKeyDeserializer if you need non-standard key parsing.
Example fix
// before: two factory methods both annotated
@JsonCreator public static Key fromString(String s) { ... }
@JsonCreator public static Key valueOf(String s) { ... }
// after: only one
@JsonCreator public static Key fromString(String s) { ... } Defensive patterns
Strategy: validation
Validate before calling
// Check for duplicate @JsonCreator factory methods at startup
List<Method> factoryMethods = Arrays.stream(MyKey.class.getMethods())
.filter(m -> m.isAnnotationPresent(JsonCreator.class))
.filter(m -> m.getParameterCount() == 1
&& m.getParameterTypes()[0] == String.class)
.toList();
if (factoryMethods.size() > 1) {
throw new IllegalStateException("Multiple key-deserializer factory methods");
} Try / catch
try {
mapper.readValue(json, new TypeReference<Map<MyKey,String>>() {});
} catch (IllegalArgumentException e) {
if (e.getMessage().contains("Multiple suitable")) {
// Remove duplicate @JsonCreator on key type factory methods
}
} Prevention
- Annotate only one String-accepting factory method as @JsonCreator on key types.
- If both valueOf and fromString exist, annotate at most one.
- Use a custom KeyDeserializer for complex key parsing logic.
When it happens
Trigger: A class used as a Map key has two or more static factory methods annotated with @JsonCreator(Mode.DELEGATING or PROPERTIES) that each accept a single String. A valueOf-like factory and a fromString-like factory both marked as creators. Using @Jacksonized with a factory method when another factory method also qualifies.
Common situations: Adding a second factory method with @JsonCreator to a class used as a map key. Library types that provide both valueOf(String) and fromString(String) with one annotated as creator. Migrating from valueOf to fromString without removing the old creator annotation.
Related errors
- AnnotationIntrospector returned key deserializer definition
- Trying to resolve a forward reference with id [{}] that wasn
- Cannot call withValueDeserializer() on {}
- Cannot pass null property name
- Duplicate creator property "%s" (index %s vs %d) for type %s
AI-assisted analysis of FasterXML/jackson-databind@a50c7d2a1d (2026-08-06).
Data as JSON: /api/errors/b75410a9e7cbdb36.
Report an issue: GitHub.