{"record":{"id":"c5525a0e5f42c259","repo":"apache/cassandra","slug":"memtable-heap-space-must-be-positive-but-was-co","errorCode":null,"errorMessage":"memtable_heap_space must be positive, but was ${conf.memtable_heap_space}","messagePattern":"memtable_heap_space must be positive, but was (.+?)","errorType":"validation","errorClass":"ConfigurationException","httpStatus":null,"severity":"error","filePath":"src/java/org/apache/cassandra/config/DatabaseDescriptor.java","lineNumber":755,"sourceCode":"            throw new ConfigurationException(\"concurrent_counter_writes must be at least 2, but was \" + conf.concurrent_counter_writes, false);\n\n        if (conf.networking_cache_size == null)\n            conf.networking_cache_size = new DataStorageSpec.IntMebibytesBound(Math.min(128, (int) (Runtime.getRuntime().maxMemory() / (16 * 1048576))));\n\n        if (conf.file_cache_size == null)\n            conf.file_cache_size = new DataStorageSpec.IntMebibytesBound(Math.min(512, (int) (Runtime.getRuntime().maxMemory() / (4 * 1048576))));\n\n        // round down for SSDs and round up for spinning disks\n        if (conf.file_cache_round_up == null)\n            conf.file_cache_round_up = conf.disk_optimization_strategy == Config.DiskOptimizationStrategy.spinning;\n\n        if (conf.memtable_offheap_space == null)\n            conf.memtable_offheap_space = new DataStorageSpec.IntMebibytesBound((int) (Runtime.getRuntime().maxMemory() / (4 * 1048576)));\n        // for the moment, we default to twice as much on-heap space as off-heap, as heap overhead is very large\n        if (conf.memtable_heap_space == null)\n            conf.memtable_heap_space = new DataStorageSpec.IntMebibytesBound((int) (Runtime.getRuntime().maxMemory() / (4 * 1048576)));\n        if (conf.memtable_heap_space.toMebibytes() == 0)\n            throw new ConfigurationException(\"memtable_heap_space must be positive, but was \" + conf.memtable_heap_space, false);\n        logger.info(\"Global memtable on-heap threshold is enabled at {}\", conf.memtable_heap_space);\n        if (conf.memtable_offheap_space.toMebibytes() == 0)\n            logger.info(\"Global memtable off-heap threshold is disabled, HeapAllocator will be used instead\");\n        else\n            logger.info(\"Global memtable off-heap threshold is enabled at {}\", conf.memtable_offheap_space);\n\n        if (conf.repair_session_max_tree_depth != null)\n        {\n            logger.warn(\"repair_session_max_tree_depth has been deprecated and should be removed from cassandra.yaml. Use repair_session_space instead\");\n            if (conf.repair_session_max_tree_depth < 10)\n                throw new ConfigurationException(\"repair_session_max_tree_depth should not be < 10, but was \" + conf.repair_session_max_tree_depth);\n            if (conf.repair_session_max_tree_depth > 20)\n                logger.warn(\"repair_session_max_tree_depth of \" + conf.repair_session_max_tree_depth + \" > 20 could lead to excessive memory usage\");\n        }\n        else\n        {\n            conf.repair_session_max_tree_depth = 20;\n        }","sourceCodeStart":737,"sourceCodeEnd":773,"githubUrl":"https://github.com/apache/cassandra/blob/88fd0f6a0eaed8943f05ac9e8f947882b8ddc8f1/src/java/org/apache/cassandra/config/DatabaseDescriptor.java#L737-L773","documentation":"memtable_heap_space_in_mb is the global on-heap memtable flush threshold; when unset it defaults to max heap / 4 MiB units. applySimpleConfig rejects a resolved value of 0 MiB, because a zero threshold would make cleanup-based memtable management either trigger constantly or never, both unsafe. The ConfigurationException fires when the explicit or derived value rounds to 0.","triggerScenarios":"Setting `memtable_heap_space_in_mb: 0` (or a sub-megabyte value that truncates to 0, e.g. 512KB) in cassandra.yaml, or running with a tiny -Xmx such that the derived default maxHeap/4 falls below 1 MiB, during DatabaseDescriptor.toolInitialization/applyAll.","commonSituations":"Embedded Cassandra usage (tests, tools like sstable utilities) with a very small heap; operators attempting to 'disable' memtable pressure tracking by setting 0; config calculators mis-converting bytes/KB/MB for the DataStorageSpec value.","solutions":["Set `memtable_heap_space_in_mb` (e.g. 256+) explicitly in cassandra.yaml, or enlarge the heap so the default is >= 1 MiB.","Remove the override so the default (max heap / 4) applies.","Fix unit suffix mistakes: the value is parsed as a DataStorageSpec.IntMebibytesBound — ensure suffixes like '256MiB' are written correctly and not '0'."],"exampleFix":"// before (cassandra.yaml)\nmemtable_heap_space_in_mb: 0\n// after (cassandra.yaml)\nmemtable_heap_space_in_mb: 1024","handlingStrategy":"validation","validationCode":"// Java, before toolInitialization()\nlong heapBytes = Runtime.getRuntime().maxMemory();\nvar raw = Config.getRawConfig();\nlong mb = raw != null && raw.memtable_heap_space != null\n        ? raw.memtable_heap_space.toMebibytes()\n        : heapBytes / (4L * 1048576L);\nif (mb <= 0)\n    throw new IllegalArgumentException(\"memtable_heap_space resolves to 0 MiB; increase heap or set it explicitly\");","typeGuard":null,"tryCatchPattern":null,"preventionTips":["Never set memtable_heap_space_in_mb to 0; there is no 'disable' via zero.","Ensure embedded/test heaps are large enough for the maxHeap/4 default to exceed 1 MiB.","Double-check duration/storage suffixes when writing DataStorageSpec values."],"tags":["config","memtable","memory","validation"],"backgroundTag":"invalid-config-value","analyzedSha":"88fd0f6a0eaed8943f05ac9e8f947882b8ddc8f1","analyzedAt":"2026-09-10T07:29:22.284Z","contentChangedAt":"2026-09-10T07:29:22.284Z","schemaVersion":2},"datasetVersion":"2026-09-14T16:17:12.679Z"}