{"record":{"id":"31a819fa7ca28a50","repo":"apache/cassandra","slug":"serialized-size-cannot-be-more-than-2gib-integer-m","errorCode":null,"errorMessage":"Serialized size cannot be more than 2GiB/Integer.MAX_VALUE","messagePattern":"Serialized size cannot be more than 2GiB/Integer\\.MAX_VALUE","errorType":"exception","errorClass":"IllegalArgumentException","httpStatus":null,"severity":"error","filePath":"src/java/org/apache/cassandra/cache/CaffeineCache.java","lineNumber":67,"sourceCode":"    /**\n     * Initialize a cache with initial capacity with weightedCapacity\n     */\n    public static <K extends IMeasurableMemory, V extends IMeasurableMemory> CaffeineCache<K, V> create(long weightedCapacity, Weigher<K, V> weigher)\n    {\n        Cache<K, V> cache = Caffeine.newBuilder()\n                .maximumWeight(weightedCapacity)\n                .weigher(weigher)\n                .executor(ImmediateExecutor.INSTANCE)\n                .build();\n        return new CaffeineCache<>(cache);\n    }\n\n    public static <K extends IMeasurableMemory, V extends IMeasurableMemory> CaffeineCache<K, V> create(long weightedCapacity)\n    {\n        return create(weightedCapacity, (key, value) -> {\n            long size = key.unsharedHeapSize() + value.unsharedHeapSize();\n            if (size > Integer.MAX_VALUE) {\n                throw new IllegalArgumentException(\"Serialized size cannot be more than 2GiB/Integer.MAX_VALUE\");\n            }\n            return (int) size;\n        });\n    }\n\n    public long capacity()\n    {\n        return policy.getMaximum();\n    }\n\n    public void setCapacity(long capacity)\n    {\n        policy.setMaximum(capacity);\n    }\n\n    public boolean isEmpty()\n    {\n        return cache.asMap().isEmpty();","sourceCodeStart":49,"sourceCodeEnd":85,"githubUrl":"https://github.com/apache/cassandra/blob/88fd0f6a0eaed8943f05ac9e8f947882b8ddc8f1/src/java/org/apache/cassandra/cache/CaffeineCache.java#L49-L85","documentation":"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.","triggerScenarios":"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).","commonSituations":"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.","solutions":["Reduce the size of the data being cached so individual entries fit under 2GiB on heap; avoid caching such large values at all.","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.","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.","Fix any custom IMeasurableMemory implementation whose unsharedHeapSize() over-reports the actual footprint."],"exampleFix":"// before\npublic static <K extends IMeasurableMemory, V extends IMeasurableMemory> CaffeineCache<K, V> create(long weightedCapacity)\n{\n    return create(weightedCapacity, (key, value) -> {\n        long size = key.unsharedHeapSize() + value.unsharedHeapSize();\n        if (size > Integer.MAX_VALUE)\n            throw new IllegalArgumentException(\"Serialized size cannot be more than 2GiB/Integer.MAX_VALUE\");\n        return (int) size;\n    });\n}\n\n// after (caller-side: keep entries small and cap capacity so oversized entries are rejected gracefully)\nlong size = key.unsharedHeapSize() + value.unsharedHeapSize();\nif (size > Integer.MAX_VALUE || size > cacheCapacity)\n    return; // skip caching this oversized entry instead of failing the put\n","handlingStrategy":"validation","validationCode":"long size = key.unsharedHeapSize() + value.unsharedHeapSize();\nif (size > Integer.MAX_VALUE)\n    throw new IllegalArgumentException(\"entry size \" + size + \" exceeds 2GiB cache weight limit\"); // or skip caching","typeGuard":"boolean cacheable(IMeasurableMemory k, IMeasurableMemory v) { return k.unsharedHeapSize() + v.unsharedHeapSize() <= Integer.MAX_VALUE; }","tryCatchPattern":"try { cache.put(key, value); }\ncatch (IllegalArgumentException e) { if (e.getMessage() != null && e.getMessage().contains(\"2GiB\")) { metrics.oversizedCacheEntryDropped.inc(); } else throw e; }","preventionTips":["Keep cache capacity settings (key_cache_size_in_mb, row_cache_size_in_mb) sane; Caffeine cannot admit entries heavier than the max weight anyway.","Avoid caching very large partitions or huge serialized values; exclude oversized entries before put.","Verify custom IMeasurableMemory implementations report accurate unsharedHeapSize values."],"tags":["cache","caffeine","memory-limit","size-limit"],"backgroundTag":"value-out-of-range","analyzedSha":"88fd0f6a0eaed8943f05ac9e8f947882b8ddc8f1","analyzedAt":"2026-09-10T07:29:22.284Z","contentChangedAt":"2026-09-10T07:29:22.284Z","schemaVersion":2},"datasetVersion":"2026-09-14T11:17:12.474Z"}