apache/druid · error · IllegalArgumentException

Index[%s] < 0

Error message

Index[%s] < 0

What it means

GenericIndexed.checkIndex() validates element access bounds; a negative index cannot address any element, so it throws IAE 'Index[i] < 0'. This guards get(int) against underflow from bad binary search results or off-by-one arithmetic.

Source

Thrown at processing/src/main/java/org/apache/druid/segment/data/GenericIndexed.java:495

      // Inspecting just one example of valueBuffer, not needed to inspect the whole array, because all buffers in it
      // are the same.
      inspector.visit("valueBuffer", valueBuffers.length > 0 ? valueBuffers[0] : null);
      inspector.visit("strategy", strategy);
    }
  }

  /**
   * Checks  if {@code index} a valid `element index` in GenericIndexed.
   * Similar to Preconditions.checkElementIndex() except this method throws {@link IAE} with custom error message.
   * <p>
   * Used here to get existing behavior(same error message and exception) of V1 GenericIndexed.
   *
   * @param index index identifying an element of an GenericIndexed.
   */
  protected void checkIndex(int index)
  {
    if (index < 0) {
      throw new IAE("Index[%s] < 0", index);
    }
    if (index >= size) {
      throw new IAE("Index[%d] >= size[%d]", index, size);
    }
  }

  public Class<? extends T> getClazz()
  {
    return strategy.getClazz();
  }

  @Override
  public int size()
  {
    return size;
  }

  /**

View on GitHub (pinned to 9b90983fd2)

Solutions

  1. Check for negative values (especially -1 from lookup/indexOf) before calling get(index).
  2. Clamp or return null early: if (idx < 0 || idx >= indexed.size()) return null;
  3. Fix upstream logic so failed lookups propagate as 'not found' instead of a negative index.

Example fix

// before
int idx = indexed.indexOf(value);
String s = indexed.get(idx);
// after
int idx = indexed.indexOf(value);
String s = idx < 0 ? null : indexed.get(idx);
Defensive patterns

Strategy: type-guard

Validate before calling

if (index < 0 || index >= indexed.size()) return null;

Type guard

boolean inBounds(Indexed<?> idx, int i) { return i >= 0 && i < idx.size(); }

Try / catch

try { return indexed.get(i); } catch (IAE e) { return null; } // treat as missing value

Prevention

When it happens

Trigger: Calling get(index) (or lookup/indexOf paths) with a negative int, typically the result of a failed binary search/lookup returning -1 that wasn't handled.

Common situations: Code that treats indexOf() miss (-1) as a valid index, arithmetic like (index - 1) underflowing at 0, or deserialized metadata containing negative offsets.

Related errors


AI-assisted analysis of apache/druid@9b90983fd2 (2026-09-07). Data as JSON: /api/errors/dcae45c54ec36644. Report an issue: GitHub.