LMAX-Exchange/disruptor · error · IllegalArgumentException
bufferSize must not be less than 1
Error message
bufferSize must not be less than 1
What it means
Defensive check in RingBufferFields' constructor: the size reported by the sequencer is not a power of 2. Disruptor indexes slots with sequence & (bufferSize - 1), which requires exactly one bit set in the size. Like error 8, this normally cannot fire with standard sequencers because AbstractSequencer already rejects non-power-of-2 sizes; it guards against faulty custom Sequencer implementations or subclasses overriding getBufferSize().
Source
Thrown at src/main/java/com/lmax/disruptor/RingBuffer.java:52
{
private static final int BUFFER_PAD = 32;
private final long indexMask;
private final E[] entries;
protected final int bufferSize;
protected final Sequencer sequencer;
@SuppressWarnings("unchecked")
RingBufferFields(
final EventFactory<E> eventFactory,
final Sequencer sequencer)
{
this.sequencer = sequencer;
this.bufferSize = sequencer.getBufferSize();
if (bufferSize < 1)
{
throw new IllegalArgumentException("bufferSize must not be less than 1");
}
if (Integer.bitCount(bufferSize) != 1)
{
throw new IllegalArgumentException("bufferSize must be a power of 2");
}
this.indexMask = bufferSize - 1;
this.entries = (E[]) new Object[bufferSize + 2 * BUFFER_PAD];
fill(eventFactory);
}
private void fill(final EventFactory<E> eventFactory)
{
for (int i = 0; i < bufferSize; i++)
{
entries[BUFFER_PAD + i] = eventFactory.newInstance();
}
}View on GitHub (pinned to c871ca4982)
Solutions
- Return a power-of-2 capacity from custom Sequencer.getBufferSize().
- Extend AbstractSequencer so constructor validation runs for you.
- When mocking, stub getBufferSize() explicitly with a power of 2 such as 1024.
Example fix
// before Sequencer mock = mock(Sequencer.class); when(mock.getBufferSize()).thenReturn(1000); RingBuffer<Event> rb = new RingBuffer<>(Event::new, mock, new BlockingWaitStrategy()); // after when(mock.getBufferSize()).thenReturn(1024);
Defensive patterns
Strategy: validation
Validate before calling
int size = customSequencer.getBufferSize();
if (Integer.bitCount(size) != 1) throw new IllegalArgumentException("sequencer bufferSize must be a power of 2, got " + size); Prevention
- Delegate size handling to AbstractSequencer in custom sequencers.
- Use power-of-2 constants in test fixtures.
When it happens
Trigger: Passing a custom Sequencer whose getBufferSize() returns e.g. 1000 into a RingBuffer constructor; a test double returning an arbitrary number; subclassing that lazily changes bufferSize after construction.
Common situations: Custom sequencer for metrics/fault injection that bypasses AbstractSequencer; Mockito Sequencer mock with an unstubbed or arbitrary getBufferSize() return value.
Related errors
- Thread is already running
- bufferSize must be a power of 2
- bufferSize must be a power of 2
- bufferSize must not be less than 1
- n must be > 0 and < bufferSize
AI-assisted analysis of LMAX-Exchange/disruptor@c871ca4982 (2026-08-14).
Data as JSON: /api/errors/d0c590df9bd4d96c.
Report an issue: GitHub.