apache/druid · error · IllegalArgumentException

Only positive integers or zero can be added

Error message

Only positive integers or zero can be added

What it means

IntegerSet is a Set<Integer> backed by a bitmap, and bitmaps can only index non-negative offsets. add() rejects null elements and any negative Integer because there is no valid bitmap slot for them. The check happens before mutating the bitmap, so the set is unchanged when this is thrown.

Source

Thrown at processing/src/main/java/org/apache/druid/collections/IntegerSet.java:93

  @Override
  public Object[] toArray()
  {
    Integer[] retval = new Integer[mutableBitmap.size()];
    int pos = 0;
    for (Integer i : this) {
      retval[pos++] = i;
    }
    return retval;
  }

  @Override
  public boolean add(Integer integer)
  {
    if (null == integer) {
      throw new NullPointerException("BitSet cannot contain null values");
    }
    if (integer < 0) {
      throw new IllegalArgumentException("Only positive integers or zero can be added");
    }
    boolean isSet = mutableBitmap.get(integer);
    mutableBitmap.add(integer.intValue());
    return !isSet;
  }

  @Override
  public boolean remove(Object o)
  {
    if (o == null) {
      throw new NullPointerException("BitSet cannot contain null values");
    }
    if (o instanceof Integer) {
      Integer integer = (Integer) o;
      boolean isSet = mutableBitmap.get(integer);
      mutableBitmap.remove(integer);
      return isSet;
    } else {

View on GitHub (pinned to 9b90983fd2)

Solutions

  1. Validate the integer is >= 0 before calling add(), and clamp or skip negatives
  2. Fix the upstream computation producing negative values (ordering, off-by-one, delta logic)
  3. If negative values are legitimate data, use a different collection (HashSet<Integer>) instead of IntegerSet
  4. Handle null separately since add(null) throws NullPointerException, not this error

Example fix

// before
set.add(delta); // throws if delta < 0
// after
if (delta != null && delta >= 0) {
  set.add(delta);
}
Defensive patterns

Strategy: validation

Validate before calling

if (value == null) throw new NullPointerException("value required");
if (value < 0) throw new IllegalArgumentException("value must be >= 0: " + value);
set.add(value);

Type guard

static boolean isAddable(Integer v) { return v != null && v >= 0; }

Try / catch

try { set.add(value); } catch (NullPointerException e) { /* null element */ } catch (IllegalArgumentException e) { /* negative element */ }

Prevention

When it happens

Trigger: Calling add() with a negative Integer (e.g. add(-1)), or passing a value resulting from arithmetic that underflows below zero. Null arguments throw the related NullPointerException instead.

Common situations: Computing offsets/deltas that can go negative (e.g. current - previous on unordered data), deserializing user or external data containing negative IDs, off-by-one index arithmetic, or autoboxing an int expression that was assumed non-negative.

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/druid@9b90983fd2 (2026-09-07). Data as JSON: /api/errors/c004a2fb5ca60504. Report an issue: GitHub.