FasterXML/jackson-databind · error · IllegalArgumentException
Cannot set maxDeserializerCacheSize to a negative value
Error message
Cannot set maxDeserializerCacheSize to a negative value
What it means
DefaultCacheProvider.Builder.maxDeserializerCacheSize(int) sets the maximum number of entries the deserializer cache (DeserializerCache) may hold; zero disables caching but negative values are nonsensical, so the builder rejects them with IllegalArgumentException. The cache stores resolved ValueDeserializers keyed by type, so a negative cap would mean 'hold fewer than nothing', which is an internal-logic error rather than a tuning choice.
Source
Thrown at src/main/java/tools/jackson/databind/cfg/DefaultCacheProvider.java:166
* Corresponds to {@link DefaultCacheProvider#_maxTypeFactoryCacheSize}.
*/
private int _maxTypeFactoryCacheSize = TypeFactory.DEFAULT_MAX_CACHE_SIZE;
Builder() { }
/**
* Define the maximum size of the {@link LookupCache} instance constructed by {@link #forDeserializerCache(DeserializationConfig)}
* and {@link #_buildCache(int)}.
* <p>
* Note that specifying a maximum size of zero prevents values from being retained in the cache.
*
* @param maxDeserializerCacheSize Size for the {@link LookupCache} to use within {@link DeserializerCache}
* @return this builder
* @throws IllegalArgumentException if {@code maxDeserializerCacheSize} is negative
*/
public Builder maxDeserializerCacheSize(int maxDeserializerCacheSize) {
if (maxDeserializerCacheSize < 0) {
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");View on GitHub (pinned to a50c7d2a1d)
Solutions
- Use 0 to disable the cache, or a large positive int (e.g. Integer.MAX_VALUE or a documented high bound) for 'effectively unlimited'.
- Validate the configured value at the configuration boundary: if (v < 0) throw new IllegalStateException(...).
- Map any '-1 means unlimited' convention at the property-reading layer to a concrete large positive value before calling the builder.
- Add a unit test asserting the builder rejects negatives and accepts 0 and large positives.
Example fix
// before
int cap = props.getInt("deser.cache.max", -1); // -1 meant 'unlimited' in old lib
DefaultCacheProvider provider = DefaultCacheProvider.builder()
.maxDeserializerCacheSize(cap).build(); // throws
// after
int cap = props.getInt("deser.cache.max", -1);
int safe = (cap < 0) ? Integer.MAX_VALUE : cap;
DefaultCacheProvider provider = DefaultCacheProvider.builder()
.maxDeserializerCacheSize(safe).build(); Defensive patterns
Strategy: validation
Validate before calling
int cap = configuredDeserCache;
if (cap < 0) throw new IllegalArgumentException("deser cache < 0: " + cap);
DefaultCacheProvider.builder().maxDeserializerCacheSize(cap).build(); Type guard
// primitive int range check
Try / catch
try {
return DefaultCacheProvider.builder().maxDeserializerCacheSize(cap).build();
} catch (IllegalArgumentException e) {
if (e.getMessage().contains("negative")) {
return DefaultCacheProvider.builder().maxDeserializerCacheSize(0).build();
}
throw e;
} Prevention
- Validate cache-size config at the property boundary; map -1 to a large positive or 0.
- Use 0 to disable caching intentionally; never pass a negative.
- Document the chosen cache semantics in your config schema.
When it happens
Trigger: Calling builder.maxDeserializerCacheSize(-1) (or any negative); computing the size from a property/expression that can go negative; passing -1 intending 'unlimited' (this builder has no unlimited sentinel — use a very large int or the default).
Common situations: A 'max cache' config where -1 was used to mean 'no limit' in another library but here means invalid; arithmetic (base - overhead) that underflows for small inputs; environment variable parsed with a default of -1 when unset.
Related errors
- Cannot set maxSerializerCacheSize to a negative value
- Cannot set maxTypeFactoryCacheSize to a negative value
- maxProblems must be positive
- maxProblems must be positive, was: {}
- AnnotationIntrospector returned Converter definition of type
AI-assisted analysis of FasterXML/jackson-databind@a50c7d2a1d (2026-08-06).
Data as JSON: /api/errors/6e05e72e6dd2bdac.
Report an issue: GitHub.