FasterXML/jackson-databind · error · IllegalArgumentException
Cannot pass null KeyDeserializers
Error message
Cannot pass null KeyDeserializers
What it means
Thrown by DeserializerFactoryConfig.withAdditionalKeyDeserializers(KeyDeserializers) when the argument is null. Key deserializers handle Map key conversion (e.g., String to enum keys); a null provider would cause NPEs during map deserialization, so it is rejected at registration time.
Solutions
- Pass a non-null KeyDeserializers instance. If you have no key deserializers, skip the call.
- Use SimpleKeyDeserializers as a concrete non-null container even when empty.
- Fix the upstream null source rather than suppressing the check.
Example fix
// before
KeyDeserializers kd = buildKeyDeserializersConditionally(); // may be null
config.withAdditionalKeyDeserializers(kd); // throws
// after
KeyDeserializers kd = buildKeyDeserializersConditionally();
if (kd != null) {
config.withAdditionalKeyDeserializers(kd);
} Defensive patterns
Strategy: validation
Validate before calling
// Validate before calling
if (keyDeserializers == null) {
throw new IllegalArgumentException("KeyDeserializers provider must not be null");
}
config.withAdditionalKeyDeserializers(keyDeserializers); Type guard
boolean isNonNullProvider(KeyDeserializers kd) {
return kd != null;
} Prevention
- Use Objects.requireNonNull(kd, "keyDeserializers") before calling.
- Guard conditional KeyDeserializers construction with null checks.
- Prefer SimpleKeyDeserializers as an empty concrete type over null.
When it happens
Trigger: Calling deserializerFactoryConfig.withAdditionalKeyDeserializers(null) directly, or via SimpleModule.set/addKeyDeserializer() internal wiring that resolves to null. Also triggered by Module.setup() implementations with conditional bugs.
Common situations: Custom modules that conditionally provide key deserializers and return null when the condition is not met. Refactoring that leaves a KeyDeserializers field uninitialized. Third-party module bugs.
Related errors
- Cannot pass null Deserializers
- AnnotationIntrospector returned Class
- AnnotationIntrospector returned key deserializer definition…
- AnnotationIntrospector.
- AnnotationIntrospector returned `Class<
AI-assisted analysis of FasterXML/jackson-databind@87876ca5c0 (2026-08-11).
Data as JSON: /api/errors/a5107e80ce5ea5f4.
Report an issue: GitHub.
Appendix: source
Thrown at src/main/java/tools/jackson/databind/cfg/DeserializerFactoryConfig.java:109
{
if (additional == null) {
throw new IllegalArgumentException("Cannot pass null Deserializers");
}
Deserializers[] all = ArrayBuilders.insertInListNoDup(_additionalDeserializers, additional);
return new DeserializerFactoryConfig(all, _additionalKeyDeserializers, _modifiers,
_valueInstantiators);
}
/**
* Fluent/factory method used to construct a configuration object that
* has same key deserializer providers as this instance, plus one specified
* as argument. Additional provider will be added before existing ones,
* meaning it has priority over existing definitions.
*/
public DeserializerFactoryConfig withAdditionalKeyDeserializers(KeyDeserializers additional)
{
if (additional == null) {
throw new IllegalArgumentException("Cannot pass null KeyDeserializers");
}
KeyDeserializers[] all = ArrayBuilders.insertInListNoDup(_additionalKeyDeserializers, additional);
return new DeserializerFactoryConfig(_additionalDeserializers, all, _modifiers,
_valueInstantiators);
}
/**
* Fluent/factory method used to construct a configuration object that
* has same configuration as this instance plus one additional
* deserialiazer modifier. Added modifier has the highest priority (that is, it
* gets called before any already registered modifier).
*/
public DeserializerFactoryConfig withDeserializerModifier(ValueDeserializerModifier modifier)
{
if (modifier == null) {
throw new IllegalArgumentException("Cannot pass null modifier");
}
ValueDeserializerModifier[] all = ArrayBuilders.insertInListNoDup(_modifiers, modifier);View on GitHub (pinned to 87876ca5c0)