{"record":{"id":"68fb2c34a56e3ba9","repo":"apache/cassandra","slug":"rowcachesaveperiodinseconds-must-be-non-negative","errorCode":null,"errorMessage":"RowCacheSavePeriodInSeconds must be non-negative.","messagePattern":"RowCacheSavePeriodInSeconds must be non-negative\\.","errorType":"validation","errorClass":"RuntimeException","httpStatus":null,"severity":"error","filePath":"src/java/org/apache/cassandra/service/CacheService.java","lineNumber":203,"sourceCode":"        logger.info(\"Scheduling counter cache save to every {} seconds (going to save {} keys).\",\n                    DatabaseDescriptor.getCounterCacheSavePeriod(),\n                    keysToSave == Integer.MAX_VALUE ? \"all\" : keysToSave);\n\n        cache.scheduleSaving(DatabaseDescriptor.getCounterCacheSavePeriod(), keysToSave);\n\n        return cache;\n    }\n\n\n    public int getRowCacheSavePeriodInSeconds()\n    {\n        return DatabaseDescriptor.getRowCacheSavePeriod();\n    }\n\n    public void setRowCacheSavePeriodInSeconds(int seconds)\n    {\n        if (seconds < 0)\n            throw new RuntimeException(\"RowCacheSavePeriodInSeconds must be non-negative.\");\n\n        DatabaseDescriptor.setRowCacheSavePeriod(seconds);\n        rowCache.scheduleSaving(seconds, DatabaseDescriptor.getRowCacheKeysToSave());\n    }\n\n    public int getKeyCacheSavePeriodInSeconds()\n    {\n        return DatabaseDescriptor.getKeyCacheSavePeriod();\n    }\n\n    public void setKeyCacheSavePeriodInSeconds(int seconds)\n    {\n        if (seconds < 0)\n            throw new RuntimeException(\"KeyCacheSavePeriodInSeconds must be non-negative.\");\n\n        DatabaseDescriptor.setKeyCacheSavePeriod(seconds);\n        keyCache.scheduleSaving(seconds, DatabaseDescriptor.getKeyCacheKeysToSave());\n    }","sourceCodeStart":185,"sourceCodeEnd":221,"githubUrl":"https://github.com/apache/cassandra/blob/88fd0f6a0eaed8943f05ac9e8f947882b8ddc8f1/src/java/org/apache/cassandra/service/CacheService.java#L185-L221","documentation":"setRowCacheSavePeriodInSeconds sets how often the row cache is persisted to disk. Negative values are invalid, so the setter throws RuntimeException before updating DatabaseDescriptor and rescheduling saving.","triggerScenarios":"Calling CacheService.setRowCacheSavePeriodInSeconds with a negative int via JMX or programmatic configuration.","commonSituations":"Operational scripts computing the save period dynamically and producing a negative value; JMX console input mistakes; config loaders that pass sentinel values like -1.","solutions":["Pass a non-negative value (0 disables periodic saving; positive seconds enable it)","Fix the script/config that computed the negative value","Use setRowCacheSavePeriodInSeconds(0) to disable saving rather than a negative number"],"exampleFix":"// before\nvoid configure(CacheService cs) { cs.setRowCacheSavePeriodInSeconds(-1); }\n// after\nvoid configure(CacheService cs) { cs.setRowCacheSavePeriodInSeconds(0); } // disable, or e.g. 60","handlingStrategy":"validation","validationCode":"if (seconds < 0) throw new IllegalArgumentException(\"RowCacheSavePeriodInSeconds must be >= 0\");\ncacheService.setRowCacheSavePeriodInSeconds(seconds);","typeGuard":null,"tryCatchPattern":"try { cacheService.setRowCacheSavePeriodInSeconds(seconds); } catch (RuntimeException e) { logger.warn(\"Rejected row cache save period: {}\", seconds); }","preventionTips":["Clamp or reject negative values in any UI/script that feeds this setter","Use 0 explicitly to disable saving instead of negative sentinels","Add a unit test asserting the setter rejects negative input"],"tags":["cache","validation","jmx"],"backgroundTag":"argument-out-of-range","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"}