FasterXML/jackson-databind · error · IllegalArgumentException

Cannot set maxTypeFactoryCacheSize to a negative value

Error message

Cannot set maxTypeFactoryCacheSize to a negative value

What it means

DefaultCacheProvider.Builder.maxTypeFactoryCacheSize(int) caps the TypeFactory's internal cache (which stores resolved JavaType instances) and throws IllegalArgumentException for negative values. Zero disables type caching (types are re-resolved each call, slower but unbounded in memory) while negative is rejected outright. This is the third symmetric guard alongside the serializer and deserializer cache caps.

Source

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

                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");
            }
            _maxTypeFactoryCacheSize = maxTypeFactoryCacheSize;
            return this;
        }

        /**
         * Constructs a {@link DefaultCacheProvider} with the provided configuration values, using defaults where not specified.
         *
         * @return A {@link DefaultCacheProvider} instance with the specified configuration
         */
        public DefaultCacheProvider build() {
            return new DefaultCacheProvider(_maxDeserializerCacheSize, _maxSerializerCacheSize, _maxTypeFactoryCacheSize);
        }
    }
}

View on GitHub (pinned to a50c7d2a1d)

Solutions

  1. Use 0 to disable type caching or a large positive int for 'effectively unlimited' (the default is already large; only lower it deliberately).
  2. Validate at the config boundary and translate -1 -> a concrete large value.
  3. If memory is the concern, prefer a modest positive cap (e.g. 4096) over disabling caching, since TypeFactory is on the hot path.
  4. Add a test that the builder rejects negatives.

Example fix

// before
int tfCap = env.get("type.cache", -1);
DefaultCacheProvider.builder().maxTypeFactoryCacheSize(tfCap).build(); // throws
// after
int tfCap = env.getInt("type.cache", 4096);
if (tfCap < 0) tfCap = Integer.MAX_VALUE;
DefaultCacheProvider.builder().maxTypeFactoryCacheSize(tfCap).build();
Defensive patterns

Strategy: validation

Validate before calling

int cap = configuredTypeCache;
if (cap < 0) throw new IllegalArgumentException("type cache < 0: " + cap);
DefaultCacheProvider.builder().maxTypeFactoryCacheSize(cap).build();

Type guard

// primitive int range check

Try / catch

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

Prevention

When it happens

Trigger: Calling builder.maxTypeFactoryCacheSize(-1) or any negative; deriving the value from a property or memory-budget calc that yields negative; a '-1 means unlimited' config convention passed through verbatim.

Common situations: Memory-budget-driven cache sizing that underflows; environment variable with a -1 default meaning 'auto'; 2.x-to-3.x migration where TypeFactory caching semantics changed and old sentinels are reused.

Related errors


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