apache/pulsar · error · IllegalArgumentException

Value out of range [0, <MAX_UINT32>]: <value>

Error message

Value out of range [0, <MAX_UINT32>]: <value>

What it means

ConcurrentRoaringBitmap.validateRange rejects values outside the unsigned 32-bit range [0, 4294967295] because the underlying RoaringBitmap stores ints; negative or >MAX_UINT32 values cannot be represented.

Source

Thrown at pulsar-common/src/main/java/org/apache/pulsar/common/util/collections/ConcurrentRoaringBitmap.java:458

        } catch (IOException e) {
            throw new RuntimeException("Failed to deserialize LongBitmap", e);
        }
    }

    /**
     * Trims the underlying bitmap if enough removals have accumulated or it's empty.
     * Caller must hold the write lock and have already updated {@link #removesSinceTrim}.
     */
    private void maybeTrim() {
        if (removesSinceTrim >= TRIM_AFTER_REMOVES || bitmap.isEmpty()) {
            bitmap.trim();
            removesSinceTrim = 0;
        }
    }

    private static void validateRange(long value) {
        if (value < 0 || value > MAX_UINT32) {
            throw new IllegalArgumentException(
                    "Value out of range [0, " + MAX_UINT32 + "]: " + value);
        }
    }

    /** Minimal {@link DataInput} over a {@link ByteBuffer} for RoaringBitmap deserialization. */
    private static final class ByteBufferDataInput implements DataInput {
        private final ByteBuffer buffer;

        ByteBufferDataInput(ByteBuffer buffer) {
            this.buffer = buffer;
        }

        @Override
        public void readFully(byte[] b) {
            buffer.get(b);
        }

        @Override

View on GitHub (pinned to 820761864e)

Solutions

  1. Use a Set/LongBitmap structure for values above 2^32-1 or negative
  2. Validate input ranges before adding to the bitmap

Example fix

// before
bitmap.add(id); // id is a 64-bit long
// after
if (id >= 0 && id <= 4294967295L) {
    bitmap.add((int) id);
} else {
    long hi = id >>> 32, lo = id & 0xFFFFFFFFL;
    bitmapsByHiWord.computeIfAbsent(hi, k -> new ConcurrentRoaringBitmap()).add(lo);
}
Defensive patterns

Strategy: validation

Validate before calling

static final long MAX_UINT32 = 4294967295L;
static boolean inBitmapRange(long v) {
    return v >= 0 && v <= MAX_UINT32;
}

Try / catch

try {
    bitmap.add(value);
} catch (IllegalArgumentException e) {
    log.warn("Value out of bitmap range: {}", value);
}

Prevention

When it happens

Trigger: Calling add/remove/checkedAdd with a negative long or a value > 4294967295 (e.g. a full unsigned-64 id, or negative sentinel).

Common situations: Storing 64-bit ledger/entry ids directly when the bitmap only fits 32-bit range; values that overflowed int arithmetic into negatives.

Understand the failure class

Background: "value must be between 0 and 1" / "out of range" / "must not be negative" errors: fixing range-validation failures across open-source libraries — this error's family across 42 libraries.

Related errors


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