apache/cassandra · error · IllegalArgumentException

Serialized size cannot be more than 2GiB/Integer.MAX_VALUE

Error message

Serialized size cannot be more than 2GiB/Integer.MAX_VALUE

What it means

CaffeineCache.create(weightedCapacity) sizes entries using an IntFunction that computes key.unsharedHeapSize() + value.unsharedHeapSize() and returns it as the Caffeine weight. Because Caffeine weights are Java ints, an entry whose combined on-heap size exceeds Integer.MAX_VALUE cannot be represented, and the weaver throws this IllegalArgumentException instead of silently miscounting. Caffeine also rejects entries whose weight is larger than the cache's maximum weight, so such an entry could never be cached anyway.

Source

Thrown at src/java/org/apache/cassandra/cache/CaffeineCache.java:67

    /**
     * Initialize a cache with initial capacity with weightedCapacity
     */
    public static <K extends IMeasurableMemory, V extends IMeasurableMemory> CaffeineCache<K, V> create(long weightedCapacity, Weigher<K, V> weigher)
    {
        Cache<K, V> cache = Caffeine.newBuilder()
                .maximumWeight(weightedCapacity)
                .weigher(weigher)
                .executor(ImmediateExecutor.INSTANCE)
                .build();
        return new CaffeineCache<>(cache);
    }

    public static <K extends IMeasurableMemory, V extends IMeasurableMemory> CaffeineCache<K, V> create(long weightedCapacity)
    {
        return create(weightedCapacity, (key, value) -> {
            long size = key.unsharedHeapSize() + value.unsharedHeapSize();
            if (size > Integer.MAX_VALUE) {
                throw new IllegalArgumentException("Serialized size cannot be more than 2GiB/Integer.MAX_VALUE");
            }
            return (int) size;
        });
    }

    public long capacity()
    {
        return policy.getMaximum();
    }

    public void setCapacity(long capacity)
    {
        policy.setMaximum(capacity);
    }

    public boolean isEmpty()
    {
        return cache.asMap().isEmpty();

View on GitHub (pinned to 88fd0f6a0e)

Solutions

  1. Reduce the size of the data being cached so individual entries fit under 2GiB on heap; avoid caching such large values at all.
  2. Lower the cache capacity (DatabaseDescriptor cache settings, e.g. key_cache_size_in_mb / row_cache_size_in_mb) so oversized entries are never admitted; Caffeine would reject them anyway.
  3. Cap the value returned by the weigher (e.g. Math.min(size, Integer.MAX_VALUE)) in the custom create overload if you control it, accepting approximate weights — but note Caffeine still cannot hold an entry heavier than maxWeight.
  4. Fix any custom IMeasurableMemory implementation whose unsharedHeapSize() over-reports the actual footprint.

Example fix

// before
public static <K extends IMeasurableMemory, V extends IMeasurableMemory> CaffeineCache<K, V> create(long weightedCapacity)
{
    return create(weightedCapacity, (key, value) -> {
        long size = key.unsharedHeapSize() + value.unsharedHeapSize();
        if (size > Integer.MAX_VALUE)
            throw new IllegalArgumentException("Serialized size cannot be more than 2GiB/Integer.MAX_VALUE");
        return (int) size;
    });
}

// after (caller-side: keep entries small and cap capacity so oversized entries are rejected gracefully)
long size = key.unsharedHeapSize() + value.unsharedHeapSize();
if (size > Integer.MAX_VALUE || size > cacheCapacity)
    return; // skip caching this oversized entry instead of failing the put
Defensive patterns

Strategy: validation

Validate before calling

long size = key.unsharedHeapSize() + value.unsharedHeapSize();
if (size > Integer.MAX_VALUE)
    throw new IllegalArgumentException("entry size " + size + " exceeds 2GiB cache weight limit"); // or skip caching

Type guard

boolean cacheable(IMeasurableMemory k, IMeasurableMemory v) { return k.unsharedHeapSize() + v.unsharedHeapSize() <= Integer.MAX_VALUE; }

Try / catch

try { cache.put(key, value); }
catch (IllegalArgumentException e) { if (e.getMessage() != null && e.getMessage().contains("2GiB")) { metrics.oversizedCacheEntryDropped.inc(); } else throw e; }

Prevention

When it happens

Trigger: Calling CaffeineCache.create(capacity) and then putting a single key/value pair whose combined unsharedHeapSize() exceeds 2GiB (e.g. a pathological multi-megabyte/large-partition cache value inflated by heap accounting, or a custom IMeasurableMemory implementation returning an inflated size). The lambda in create throws when Caffeine calls weigher.apply(key, value).

Common situations: A single cached value larger than 2GiB on heap (huge partitions cached in a key/row cache with an oversized capacity setting); a buggy custom IMeasurableMemory measure returning wrong sizes; memory accounting changes across JVM versions inflating unsharedHeapSize for large objects.

Understand the failure class

Background: "value must be between 0 and 1" / "out of range" / "must not be negative" errors: fixing range-validation failures across open-source libraries — this error's family across 42 libraries.

Related errors


AI-assisted analysis of apache/cassandra@88fd0f6a0e (2026-09-10). Data as JSON: /api/errors/31a819fa7ca28a50. Report an issue: GitHub.