apache/pulsar · error · IndexOutOfBoundsException

bitIndex < 0: <bitIndex>

Error message

bitIndex < 0: <bitIndex>

What it means

BitSetRecyclable.flip(int bitIndex) requires a non-negative bit index; negative indices cannot map to a valid word/bit position, so the method throws IndexOutOfBoundsException immediately. This matches java.util.BitSet behavior. It is a caller argument error, not internal state corruption.

Source

Thrown at pulsar-common/src/main/java/org/apache/pulsar/common/util/collections/BitSetRecyclable.java:357

            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);

        words[wordIndex] ^= (1L << bitIndex);

        recalculateWordsInUse();
        checkInvariants();
    }

    /**
     * Sets each bit from the specified {@code fromIndex} (inclusive) to the
     * specified {@code toIndex} (exclusive) to the complement of its current
     * value.
     *
     * @param  fromIndex index of the first bit to flip
     * @param  toIndex index after the last bit to flip
     * @throws IndexOutOfBoundsException if {@code fromIndex} is negative,

View on GitHub (pinned to 820761864e)

Solutions

  1. Inspect where the negative index originates and fix the computation or lookup that produced -1/underflow
  2. Guard the call: only flip when bitIndex >= 0
  3. Validate protocol/batch-index values before they reach the bit set
  4. Add a test for negative or 'not found' sentinel inputs

Example fix

// before
int idx = findBatchIndex(msg); // may return -1
bitSet.flip(idx);
// after
int idx = findBatchIndex(msg);
if (idx >= 0) {
    bitSet.flip(idx);
}
Defensive patterns

Strategy: validation

Validate before calling

if (bitIndex < 0) {
    throw new IllegalArgumentException("bitIndex must be >= 0, got " + bitIndex);
}
bitSet.flip(bitIndex);

Type guard

static boolean isValidBitIndex(int idx) { return idx >= 0; }

Try / catch

try {
    bitSet.flip(bitIndex);
} catch (IndexOutOfBoundsException e) {
    LOG.warn("negative bitIndex {} passed to flip", bitIndex, e);
}

Prevention

When it happens

Trigger: Calling flip() with a negative bitIndex, typically a result of an uninitialized variable, an unset array lookup returning -1 (e.g. indexOf-style probes), or an arithmetic underflow computing the index.

Common situations: Using the result of a lookup that returns -1 for 'not found' directly as a bit index; batch index acknowledgment where a computed batch index went negative; integer overflow when multiplying message position components.

Related errors


AI-assisted analysis of apache/pulsar@820761864e (2026-09-06). Data as JSON: /api/errors/b13831deef5b0c25. Report an issue: GitHub.