apache/pulsar · error · IndexOutOfBoundsException
fromIndex: <fromIndex> > toIndex: <toIndex>
Error message
fromIndex: <fromIndex> > toIndex: <toIndex>
What it means
BitSetRecyclable.checkRange validates index ranges for the range-based flip(int,int), set(int,int) and clear(int,int) methods (and the get(int,int) read path). When fromIndex is greater than toIndex the range is empty/malformed, so the method throws IndexOutOfBoundsException instead of silently doing nothing. It is a caller-contract violation mirroring java.util.BitSet semantics.
Source
Thrown at pulsar-common/src/main/java/org/apache/pulsar/common/util/collections/BitSetRecyclable.java:343
*/
private void expandTo(int wordIndex) {
int wordsRequired = wordIndex+1;
if (wordsInUse < wordsRequired) {
ensureCapacity(wordsRequired);
wordsInUse = wordsRequired;
}
}
/**
* Checks that fromIndex ... toIndex is a valid range of bit indices.
*/
private static void checkRange(int fromIndex, int toIndex) {
if (fromIndex < 0)
throw new IndexOutOfBoundsException("fromIndex < 0: " + fromIndex);
if (toIndex < 0)
throw new IndexOutOfBoundsException("toIndex < 0: " + toIndex);
if (fromIndex > toIndex)
throw new IndexOutOfBoundsException("fromIndex: " + fromIndex +
" > toIndex: " + toIndex);
}
/**
* Sets the bit at the specified index to the complement of its
* current value.
*
* @param bitIndex the index of the bit to flip
* @throws IndexOutOfBoundsException if the specified index is negative
* @since 1.4
*/
public void flip(int bitIndex) {
if (bitIndex < 0)
throw new IndexOutOfBoundsException("bitIndex < 0: " + bitIndex);
int wordIndex = wordIndex(bitIndex);
expandTo(wordIndex);
View on GitHub (pinned to 820761864e)
Solutions
- Check the call site and ensure arguments are passed as (fromIndex, toIndex) with fromIndex <= toIndex
- Guard or normalize the range before calling: fromIndex = Math.min(a,b); toIndex = Math.max(a,b)
- Skip the call when the range is empty (fromIndex == toIndex only clears/sets nothing for ranges) or log the source of the inverted range
- Add a unit test covering inverted ranges if the indices come from user/protocol data
Example fix
// before
bitSet.flip(endIndex, startIndex);
// after
if (startIndex <= endIndex) {
bitSet.flip(startIndex, endIndex);
} Defensive patterns
Strategy: validation
Validate before calling
if (fromIndex < 0 || toIndex < 0) throw new IllegalArgumentException("negative index");
if (fromIndex > toIndex) throw new IllegalArgumentException("fromIndex " + fromIndex + " > toIndex " + toIndex); Try / catch
try {
bitSet.set(fromIndex, toIndex);
} catch (IndexOutOfBoundsException e) {
LOG.warn("invalid range [{}, {}]", fromIndex, toIndex, e);
} Prevention
- Normalize ranges with Math.min/Math.max before calling
- Keep (from, to) argument order consistent; avoid positional swaps in refactors
- Validate user/protocol-derived ranges at the boundary
- Unit-test inverted and empty ranges
When it happens
Trigger: Calling BitSetRecyclable.flip(int,int), set(int,int), clear(int,int) or get(int,int) with fromIndex > toIndex, e.g. after swapping variables, computing indices from min/max incorrectly, or building a range from user input where the start can exceed the end.
Common situations: Batch-acknowledgment code computing message ranges from data where the range is inverted (end before start after sorting changes); off-by-one loops passing (i, j) in the wrong order; refactoring a single-bit call into a range call and swapping arguments.
Related errors
- fromIndex < 0: <fromIndex>
- toIndex < 0: <toIndex>
- bitIndex < 0: <bitIndex>
- fromIndex < -1: <fromIndex>
- nbits < 0: <nbits>
AI-assisted analysis of apache/pulsar@820761864e (2026-09-06).
Data as JSON: /api/errors/540e879d3f83d548.
Report an issue: GitHub.