{"record":{"id":"e2898823c85d4e1c","repo":"apache/cassandra","slug":"invalid-data-rate-value-must-be-non-negative","errorCode":null,"errorMessage":"Invalid data rate: value must be non-negative","messagePattern":"Invalid data rate: value must be non-negative","errorType":"validation","errorClass":"IllegalArgumentException","httpStatus":null,"severity":"error","filePath":"src/java/org/apache/cassandra/config/DataRateSpec.java","lineNumber":87,"sourceCode":"    {\n        this.quantity = quantity;\n        this.unit = unit;\n\n        validateQuantity(quantity, unit, minUnit, max);\n    }\n\n    private static void validateQuantity(String value, double quantity, DataRateUnit unit, DataRateUnit minUnit, long max)\n    {\n        // negatives are not allowed by the regex pattern\n        if (minUnit.convert(quantity, unit) >= max)\n            throw new IllegalArgumentException(\"Invalid data rate: \" + value + \". It shouldn't be more than \" +\n                                             (max - 1) + \" in \" + toLowerCaseLocalized(minUnit.name()));\n    }\n\n    private static void validateQuantity(double quantity, DataRateUnit unit, DataRateUnit minUnit, long max)\n    {\n        if (quantity < 0)\n            throw new IllegalArgumentException(\"Invalid data rate: value must be non-negative\");\n\n        if (minUnit.convert(quantity, unit) >= max)\n            throw new IllegalArgumentException(String.format(\"Invalid data rate: %s %s. It shouldn't be more than %d in %s\",\n                                                       quantity, toLowerCaseLocalized(unit.name()),\n                                                       max - 1, toLowerCaseLocalized(minUnit.name())));\n    }\n\n    // get vs no-get prefix is not consistent in the code base, but for classes involved with config parsing, it is\n    // imporant to be explicit about get/set as this changes how parsing is done; this class is a data-type, so is\n    // not nested, having get/set can confuse parsing thinking this is a nested type\n    /**\n     * @return the data rate unit assigned.\n     */\n    public DataRateUnit unit()\n    {\n        return unit;\n    }\n","sourceCodeStart":69,"sourceCodeEnd":105,"githubUrl":"https://github.com/apache/cassandra/blob/88fd0f6a0eaed8943f05ac9e8f947882b8ddc8f1/src/java/org/apache/cassandra/config/DataRateSpec.java#L69-L105","documentation":"The double-quantity overload of DataRateSpec.validateQuantity rejects negative rate values with this IllegalArgumentException. The string-form parser's regex already forbids negatives, so this path guards programmatic construction (e.g. Java setters or code building a DataRateSpec directly).","triggerScenarios":"Calling a DataRateSpec programmatic constructor/setter (e.g. DataRateSpec.DataRate with a double) with a negative quantity such as -10 MiB/s.","commonSituations":"Code computing rates from measurements that can be negative (deltas); misconfigured formulas; tests passing -1 as a default; converting from a signed value read elsewhere without clamping.","solutions":["Clamp or fix the computed quantity to zero or greater before constructing the DataRateSpec","Validate upstream input (YAML, JMX, user code) for negativity before conversion","Use Math.max(0, value) at the call site when negative values are semantically meaningless","If a negative value indicates a logic error, fix the producer of the value instead of masking it"],"exampleFix":"// before\nDataRateSpec.DataRate rate = new DataRateSpec.DataRate(measuredRate, DataRateUnit.MIB_PER_SECOND);\n// after\nDataRateSpec.DataRate rate = new DataRateSpec.DataRate(Math.max(0, measuredRate), DataRateUnit.MIB_PER_SECOND);","handlingStrategy":"validation","validationCode":"if (!(quantity >= 0))\n    throw new IllegalArgumentException(\"Rate must be non-negative, got: \" + quantity);","typeGuard":null,"tryCatchPattern":"try {\n    rate = new DataRateSpec.DataRate(quantity, unit);\n} catch (IllegalArgumentException e) {\n    logger.warn(\"Negative rate clamped to 0\", e);\n    rate = new DataRateSpec.DataRate(0, unit);\n}","preventionTips":["Clamp computed rates with Math.max(0, x) before constructing specs","Treat negative rates as producer bugs and fix upstream math","Validate external inputs before conversion"],"tags":["configuration","validation","range"],"backgroundTag":"invalid-argument-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"}