Netflix/Hystrix · error · IllegalArgumentException

The timeInMilliseconds must divide equally into numberOfBuck

Error message

The timeInMilliseconds must divide equally into numberOfBuckets. For example 1000/10 is ok, 1000/11 is not.

What it means

HystrixRollingPercentile - the structure behind Hystrix's latency percentiles (metrics.rollingPercentile.*) - divides its window timeInMilliseconds into numberOfBuckets and requires an exact division. If timeInMilliseconds % numberOfBuckets != 0, the constructor throws IllegalArgumentException because bucket boundaries could not be computed consistently.

Source

Thrown at hystrix-core/src/main/java/com/netflix/hystrix/util/HystrixRollingPercentile.java:126

     * @param enabled
     *            {@code HystrixProperty<Boolean>} whether data should be tracked and percentiles calculated.
     *            <p>
     *            If 'false' methods will do nothing.
     */
    public HystrixRollingPercentile(int timeInMilliseconds, int numberOfBuckets, int bucketDataLength, HystrixProperty<Boolean> enabled) {
        this(ACTUAL_TIME, timeInMilliseconds, numberOfBuckets, bucketDataLength, enabled);

    }

    /* package for testing */ HystrixRollingPercentile(Time time, int timeInMilliseconds, int numberOfBuckets, int bucketDataLength, HystrixProperty<Boolean> enabled) {
        this.time = time;
        this.timeInMilliseconds = timeInMilliseconds;
        this.numberOfBuckets = numberOfBuckets;
        this.bucketDataLength = bucketDataLength;
        this.enabled = enabled;

        if (this.timeInMilliseconds % this.numberOfBuckets != 0) {
            throw new IllegalArgumentException("The timeInMilliseconds must divide equally into numberOfBuckets. For example 1000/10 is ok, 1000/11 is not.");
        }
        this.bucketSizeInMilliseconds = this.timeInMilliseconds / this.numberOfBuckets;

        buckets = new BucketCircularArray(this.numberOfBuckets);
    }

    /**
     * Add value (or values) to current bucket.
     * 
     * @param value
     *            Value to be stored in current bucket such as execution latency in milliseconds
     */
    public void addValue(int... value) {
        /* no-op if disabled */
        if (!enabled.get())
            return;

        for (int v : value) {

View on GitHub (pinned to 5ce3bc58c3)

Solutions

  1. Choose an evenly divisible (timeInMilliseconds, numBuckets) pair, e.g. 60000ms/12 or 10000ms/10.
  2. Validate the pair at application startup when both values come from external config, and fail with an explicit message.
  3. Remember each bucket must also hold bucketDataLength samples; prefer leaving rollingPercentile defaults unless you need finer granularity.

Example fix

# before
hystrix.command.orders.metrics.rollingPercentile.timeInMilliseconds=10000
hystrix.command.orders.metrics.rollingPercentile.numBuckets=6   # 10000 % 6 != 0

# after
hystrix.command.orders.metrics.rollingPercentile.timeInMilliseconds=12000
hystrix.command.orders.metrics.rollingPercentile.numBuckets=6   # 2000ms buckets
Defensive patterns

Strategy: validation

Validate before calling

static void checkPercentileWindow(int timeMs, int numBuckets) {
    if (timeMs % numBuckets != 0) {
        throw new IllegalArgumentException("rollingPercentile timeInMilliseconds must be divisible by numBuckets");
    }
}

Prevention

When it happens

Trigger: Setting hystrix.command.<key>.metrics.rollingPercentile.timeInMilliseconds and .numBuckets to an indivisible pair (e.g. 1000ms with 6 buckets is fine, 1000ms with 7 buckets throws); constructing HystrixRollingPercentile directly with such values in tests or custom metrics.

Common situations: Tuning percentile windows without recomputing divisibility (e.g. changing timeInMilliseconds to 7000 while leaving numBuckets=10); default-mismatch after merging config files from different projects.

Related errors


AI-assisted analysis of Netflix/Hystrix@5ce3bc58c3 (2026-08-14). Data as JSON: /api/errors/811444e909a735b0. Report an issue: GitHub.