FasterXML/jackson-databind · error · IllegalArgumentException

Cannot pass null Deserializers

Error message

Cannot pass null Deserializers

What it means

DeserializerFactoryConfig.withAdditionalDeserializers(Deserializers) is the fluent method used (typically by modules) to register an additional Deserializers provider. It rejects null because silently accepting null would later cause NPEs deep in factory resolution; instead it fails fast at registration time with a clear message. This is the entry point SimpleModule.addDeserializer and similar module wiring ultimately call.

Source

Thrown at src/main/java/tools/jackson/databind/cfg/DeserializerFactoryConfig.java:93

    {
        _additionalDeserializers = (allAdditionalDeserializers == null) ?
                NO_DESERIALIZERS : allAdditionalDeserializers;
        _additionalKeyDeserializers = (allAdditionalKeyDeserializers == null) ?
                DEFAULT_KEY_DESERIALIZERS : allAdditionalKeyDeserializers;
        _modifiers = (modifiers == null) ? NO_MODIFIERS : modifiers;
        _valueInstantiators = (vi == null) ? NO_VALUE_INSTANTIATORS : vi;
    }

    /**
     * Fluent/factory method used to construct a configuration object that
     * has same 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 withAdditionalDeserializers(Deserializers additional)
    {
        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);

View on GitHub (pinned to a50c7d2a1d)

Solutions

  1. In module wiring, only call withAdditionalDeserializers when the provider is non-null (guard with if (d != null)).
  2. Ensure the Deserializers instance is fully constructed before registration; inject its dependencies eagerly.
  3. Filter nulls out of provider collections before registering: providers.stream().filter(Objects::nonNull).forEach(...).
  4. Add a null-check in your module's addDeserializers to log/skip instead of forwarding null.

Example fix

// before
Deserializers custom = featureEnabled ? buildCustom() : null;
cfg.withAdditionalDeserializers(custom); // throws when disabled
// after
Deserializers custom = featureEnabled ? buildCustom() : null;
if (custom != null) cfg.withAdditionalDeserializers(custom);
Defensive patterns

Strategy: validation

Validate before calling

Deserializers d = ...;
if (d == null) throw new IllegalArgumentException("Deserializers must not be null");
cfg.withAdditionalDeserializers(d);

Type guard

// non-null reference check

Try / catch

try {
    cfg.withAdditionalDeserializers(d);
} catch (IllegalArgumentException e) {
    if (e.getMessage().equals("Cannot pass null Deserializers")) {
        // skip registration or build a default provider
    }
    throw e;
}

Prevention

When it happens

Trigger: Calling config.withAdditionalDeserializers(null), or a module's setupModule/addDeserializers forwarding a null Deserializers (e.g. a lazily-built provider that was never constructed); a list/loop registering providers where one element is null.

Common situations: A module that conditionally registers a Deserializers but builds it to null when a feature flag is off; copy-paste module wiring missing the constructor argument; a DI-provided Deserializers bean that is null because its dependency is missing; array/list of providers containing a null entry from a filtered stream.

Related errors


AI-assisted analysis of FasterXML/jackson-databind@a50c7d2a1d (2026-08-06). Data as JSON: /api/errors/4ebb38136b10b906. Report an issue: GitHub.