FasterXML/jackson-databind · error · IllegalArgumentException

Cannot set maxSerializerCacheSize to a negative value

Error message

Cannot set maxSerializerCacheSize to a negative value

What it means

DefaultCacheProvider.Builder.maxSerializerCacheSize(int) sets the cap for the serializer cache (SerializerCache) and rejects negative values with IllegalArgumentException. Zero disables caching (serializers are rebuilt each time) but a negative size is invalid. This guards the serializer side symmetrically with the deserializer cache guard.

Source

Thrown at src/main/java/tools/jackson/databind/cfg/DefaultCacheProvider.java:184

                throw new IllegalArgumentException("Cannot set maxDeserializerCacheSize to a negative value");
            }
            _maxDeserializerCacheSize = maxDeserializerCacheSize;
            return this;
        }

        /**
         * Define the maximum size of the {@link LookupCache} instance constructed by {@link #forSerializerCache(SerializationConfig)}
         * and {@link #_buildCache(int)}
         * <p>
         * Note that specifying a maximum size of zero prevents values from being retained in the cache.
         *
         * @param maxSerializerCacheSize Size for the {@link LookupCache} to use within {@link SerializerCache}
         * @return this builder
         * @throws IllegalArgumentException if {@code maxSerializerCacheSize} is negative
         */
        public Builder maxSerializerCacheSize(int maxSerializerCacheSize) {
            if (maxSerializerCacheSize < 0) {
                throw new IllegalArgumentException("Cannot set maxSerializerCacheSize to a negative value");
            }
            _maxSerializerCacheSize = maxSerializerCacheSize;
            return this;
        }

        /**
         * Define the maximum size of the {@link LookupCache} instance constructed by {@link #forTypeFactory()}
         * and {@link #_buildCache(int)}
         * <p>
         * Note that specifying a maximum size of zero prevents values from being retained in the cache.
         *
         * @param maxTypeFactoryCacheSize Size for the {@link LookupCache} to use within {@link tools.jackson.databind.type.TypeFactory}
         * @return this builder
         * @throws IllegalArgumentException if {@code maxTypeFactoryCacheSize} is negative
         */
        public Builder maxTypeFactoryCacheSize(int maxTypeFactoryCacheSize) {
            if (maxTypeFactoryCacheSize < 0) {
                throw new IllegalArgumentException("Cannot set maxTypeFactoryCacheSize to a negative value");

View on GitHub (pinned to a50c7d2a1d)

Solutions

  1. Use 0 to disable caching or a large positive int for 'effectively unlimited'; never pass a negative.
  2. Sanitize external config values: Math.max(0, configured) at the read boundary.
  3. Document the 'unlimited' choice explicitly as a large int in your config schema.
  4. Add a test for the builder rejecting negatives.

Example fix

// before
DefaultCacheProvider p = DefaultCacheProvider.builder()
    .maxSerializerCacheSize(config.getSerCacheMax()).build(); // throws when -1
// after
int ser = Math.max(0, config.getSerCacheMax());
DefaultCacheProvider p = DefaultCacheProvider.builder()
    .maxSerializerCacheSize(ser).build();
Defensive patterns

Strategy: validation

Validate before calling

int cap = configuredSerCache;
if (cap < 0) throw new IllegalArgumentException("ser cache < 0: " + cap);
DefaultCacheProvider.builder().maxSerializerCacheSize(cap).build();

Type guard

// primitive int range check

Try / catch

try {
    return DefaultCacheProvider.builder().maxSerializerCacheSize(cap).build();
} catch (IllegalArgumentException e) {
    if (e.getMessage().contains("negative")) {
        return DefaultCacheProvider.builder().maxSerializerCacheSize(0).build();
    }
    throw e;
}

Prevention

When it happens

Trigger: Calling builder.maxSerializerCacheSize(-1) or any negative; computing the cap from a formula or external config that underflows; reusing a '-1 sentinel' convention from another caching library.

Common situations: Property-driven cache tuning where the default is -1; arithmetic like (availableMemory - reserved) going negative on small heaps; migrating from 2.x cache settings that used different sentinels.

Related errors


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