nathanmarz/storm · error · IllegalArgumentException

numBuckets must be >= 2

Error message

numBuckets must be >= 2

What it means

Thrown by the RotatingMap constructor as a guard against an invalid numBuckets argument: a rotating-bucket expiration map needs at least 2 buckets because rotation always leaves one bucket untouched per cycle, and with fewer than 2 buckets items would expire immediately or rotation would be meaningless.

Solutions

  1. Construct RotatingMap with numBuckets >= 2.
  2. Use the no-arg constructor (defaults to 3 buckets) when unsure.
  3. Review any configuration value feeding numBuckets (e.g. from topology config) and clamp it to a minimum of 2.
  4. Recall bucket count affects expiration timing: effective expiry is between numBuckets and 2*numBuckets rotation periods.
Defensive patterns

Strategy: validation

When it happens

Trigger: Thrown at storm-core/src/jvm/backtype/storm/utils/RotatingMap.java:50 when the library encounters an invalid state.

Common situations: See trigger scenarios.


AI-assisted analysis of nathanmarz/storm@cdb116e942 (2026-09-12). Data as JSON: /api/errors/ccf60c828428270f. Report an issue: GitHub.

Appendix: source

Thrown at storm-core/src/jvm/backtype/storm/utils/RotatingMap.java:50

 *
 * The advantage of this design is that the expiration thread only locks the object
 * for O(1) time, meaning the object is essentially always available for gets/puts.
 */
public class RotatingMap<K, V> {
    //this default ensures things expire at most 50% past the expiration time
    private static final int DEFAULT_NUM_BUCKETS = 3;

    public static interface ExpiredCallback<K, V> {
        public void expire(K key, V val);
    }

    private LinkedList<HashMap<K, V>> _buckets;

    private ExpiredCallback _callback;
    
    public RotatingMap(int numBuckets, ExpiredCallback<K, V> callback) {
        if(numBuckets<2) {
            throw new IllegalArgumentException("numBuckets must be >= 2");
        }
        _buckets = new LinkedList<HashMap<K, V>>();
        for(int i=0; i<numBuckets; i++) {
            _buckets.add(new HashMap<K, V>());
        }

        _callback = callback;
    }

    public RotatingMap(ExpiredCallback<K, V> callback) {
        this(DEFAULT_NUM_BUCKETS, callback);
    }

    public RotatingMap(int numBuckets) {
        this(numBuckets, null);
    }   
    
    public Map<K, V> rotate() {

View on GitHub (pinned to cdb116e942)