apache/cassandra · error · IllegalArgumentException

Invalid data rate: value must be non-negative

Error message

Invalid data rate: value must be non-negative

What it means

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).

Source

Thrown at src/java/org/apache/cassandra/config/DataRateSpec.java:87

    {
        this.quantity = quantity;
        this.unit = unit;

        validateQuantity(quantity, unit, minUnit, max);
    }

    private static void validateQuantity(String value, double quantity, DataRateUnit unit, DataRateUnit minUnit, long max)
    {
        // negatives are not allowed by the regex pattern
        if (minUnit.convert(quantity, unit) >= max)
            throw new IllegalArgumentException("Invalid data rate: " + value + ". It shouldn't be more than " +
                                             (max - 1) + " in " + toLowerCaseLocalized(minUnit.name()));
    }

    private static void validateQuantity(double quantity, DataRateUnit unit, DataRateUnit minUnit, long max)
    {
        if (quantity < 0)
            throw new IllegalArgumentException("Invalid data rate: value must be non-negative");

        if (minUnit.convert(quantity, unit) >= max)
            throw new IllegalArgumentException(String.format("Invalid data rate: %s %s. It shouldn't be more than %d in %s",
                                                       quantity, toLowerCaseLocalized(unit.name()),
                                                       max - 1, toLowerCaseLocalized(minUnit.name())));
    }

    // get vs no-get prefix is not consistent in the code base, but for classes involved with config parsing, it is
    // imporant to be explicit about get/set as this changes how parsing is done; this class is a data-type, so is
    // not nested, having get/set can confuse parsing thinking this is a nested type
    /**
     * @return the data rate unit assigned.
     */
    public DataRateUnit unit()
    {
        return unit;
    }

View on GitHub (pinned to 88fd0f6a0e)

Solutions

  1. Clamp or fix the computed quantity to zero or greater before constructing the DataRateSpec
  2. Validate upstream input (YAML, JMX, user code) for negativity before conversion
  3. Use Math.max(0, value) at the call site when negative values are semantically meaningless
  4. If a negative value indicates a logic error, fix the producer of the value instead of masking it

Example fix

// before
DataRateSpec.DataRate rate = new DataRateSpec.DataRate(measuredRate, DataRateUnit.MIB_PER_SECOND);
// after
DataRateSpec.DataRate rate = new DataRateSpec.DataRate(Math.max(0, measuredRate), DataRateUnit.MIB_PER_SECOND);
Defensive patterns

Strategy: validation

Validate before calling

if (!(quantity >= 0))
    throw new IllegalArgumentException("Rate must be non-negative, got: " + quantity);

Try / catch

try {
    rate = new DataRateSpec.DataRate(quantity, unit);
} catch (IllegalArgumentException e) {
    logger.warn("Negative rate clamped to 0", e);
    rate = new DataRateSpec.DataRate(0, unit);
}

Prevention

When it happens

Trigger: Calling a DataRateSpec programmatic constructor/setter (e.g. DataRateSpec.DataRate with a double) with a negative quantity such as -10 MiB/s.

Common situations: 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.

Understand the failure class

Background: "Must be a positive integer", "Invalid value", "Unsupported": the invalid-argument-value error family, when a library rejects the value you pass — this error's family across 35 libraries.

Related errors


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