apache/cassandra · error · IllegalArgumentException

maxdevs must be greater than or equal to zero

Error message

maxdevs must be greater than or equal to zero

What it means

HistogramBuilder.buildWithStdevRangesAroundMean(maxdevs) builds an EstimatedHistogram covering up to maxdevs standard deviations around the mean. A negative maxdevs is meaningless, so it throws IllegalArgumentException immediately.

Solutions

  1. Pass a non-negative maxdevs (usually a small positive integer like 2 or 3)
  2. Clamp negative values with Math.max(0, maxdevs)
  3. Validate the configuration value where it is parsed

Example fix

// before
EstimatedHistogram h = builder.buildWithStdevRangesAroundMean(cfg.deviationCount);
// after
EstimatedHistogram h = builder.buildWithStdevRangesAroundMean(Math.max(0, cfg.deviationCount));
Defensive patterns

Strategy: validation

Validate before calling

if (maxdevs < 0) throw new IllegalArgumentException("maxdevs must be >= 0");

Try / catch

try { h = builder.buildWithStdevRangesAroundMean(maxdevs); } catch (IllegalArgumentException e) { h = builder.buildWithStdevRangesAroundMean(0); }

Prevention

When it happens

Trigger: Calling buildWithStdevRangesAroundMean with a negative int, typically from an unvalidated config value or a computed value that can go negative.

Common situations: Configured deviation count read from properties/yaml without validation; arithmetic like (max - min) gone negative; off-by-sign bugs in tooling code.

Related errors


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

Appendix: source

Thrown at src/java/org/apache/cassandra/utils/HistogramBuilder.java:73

    {
        return buildWithStdevRangesAroundMean(3);
    }

    /**
     * Calculate the min, mean, max and standard deviation of the items in the builder, and
     * generate an EstimatedHistogram with upto <code>maxdev</code> stdev size ranges  either
     * side of the mean, until min/max are hit; if either min/max are not reached a further range is
     * inserted at the relevant ends. e.g., with a <code>maxdevs</code> of 3, there may be <i>up to</i> 8 ranges
     * (between 9 boundaries, the middle being the mean); the middle 6 will have the same size (stdev)
     * with the outermost two stretching out to min and max.
     *
     * @param maxdevs
     * @return
     */
    public EstimatedHistogram buildWithStdevRangesAroundMean(int maxdevs)
    {
        if (maxdevs < 0)
            throw new IllegalArgumentException("maxdevs must be greater than or equal to zero");

        final int count = this.count;
        final long[] values = this.values;

        if (count == 0)
            return new EstimatedHistogram(EMPTY_LONG_ARRAY, ZERO);

        long min = Long.MAX_VALUE, max = Long.MIN_VALUE;
        double sum = 0, sumsq = 0;
        for (int i = 0 ; i < count ; i++)
        {
            final long value = values[i];
            sum += value;
            sumsq += value * value;
            if (value < min)
                min = value;
            if (value > max)
                max = value;

View on GitHub (pinned to 88fd0f6a0e)