LMAX-Exchange/disruptor · error · IllegalArgumentException
bufferSize must not be less than 1
Error message
bufferSize must not be less than 1
What it means
Thrown by the AbstractSequencer constructor when the ring buffer size passed to a Disruptor/RingBuffer is less than 1. Disruptor requires a strictly positive capacity because the ring buffer is an array-backed circular buffer; a zero or negative size cannot hold any entries. This is a fail-fast configuration error raised before any resource is allocated.
Source
Thrown at src/main/java/com/lmax/disruptor/AbstractSequencer.java:48
private static final AtomicReferenceFieldUpdater<AbstractSequencer, Sequence[]> SEQUENCE_UPDATER =
AtomicReferenceFieldUpdater.newUpdater(AbstractSequencer.class, Sequence[].class, "gatingSequences");
protected final int bufferSize;
protected final WaitStrategy waitStrategy;
protected final Sequence cursor = new Sequence(Sequencer.INITIAL_CURSOR_VALUE);
protected volatile Sequence[] gatingSequences = new Sequence[0];
/**
* Create with the specified buffer size and wait strategy.
*
* @param bufferSize The total number of entries, must be a positive power of 2.
* @param waitStrategy The wait strategy used by this sequencer
*/
public AbstractSequencer(final int bufferSize, final WaitStrategy waitStrategy)
{
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.bufferSize = bufferSize;
this.waitStrategy = waitStrategy;
}
/**
* @see Sequencer#getCursor()
*/
@Override
public final long getCursor()
{
return cursor.get();
}View on GitHub (pinned to c871ca4982)
Solutions
- Check the value passed as bufferSize and ensure it is >= 1 before constructing the Disruptor.
- If the size comes from configuration, validate it at startup and fail with a clear message naming the property.
- Choose a power-of-2 size (e.g. 1024, 4096) so you also satisfy the power-of-2 check that runs immediately after this one.
Example fix
// before
Disruptor<Event> d = new Disruptor<>(Event::new, config.getBufferSize(), threadFactory); // getBufferSize() returns 0
// after
int size = config.getBufferSize();
if (size < 1) throw new IllegalArgumentException("config.bufferSize must be >= 1, got " + size);
Disruptor<Event> d = new Disruptor<>(Event::new, size, threadFactory); Defensive patterns
Strategy: validation
Validate before calling
int size = config.getBufferSize();
if (size < 1) throw new IllegalArgumentException("bufferSize must be >= 1, got " + size); Prevention
- Validate all Disruptor sizing inputs at configuration load time, naming the offending property.
- Keep buffer sizes as named constants (e.g. RING_SIZE = 1024) instead of computed expressions.
When it happens
Trigger: Constructing a Disruptor or RingBuffer with bufferSize <= 0, e.g. new Disruptor<>(factory, 0, threadFactory), or creating a sequencer directly (new MultiProducerSequencer(0, waitStrategy)). Typically happens when the size is computed from configuration, a system property, or an expression that evaluates to 0 (e.g. uninitialised int field, empty list size, integer underflow).
Common situations: Size read from a config file/env var that is missing and defaults to 0; capacity derived from partition count or thread count that is 0 in a test environment; off-by-one math producing a negative value; refactoring that moved buffer creation before the size is initialised.
Related errors
- bufferSize must be a power of 2
- value must be a positive number
- maxBatchSize must be greater than 0
- n must be > 0 and < bufferSize
- Thread is already running
AI-assisted analysis of LMAX-Exchange/disruptor@c871ca4982 (2026-08-14).
Data as JSON: /api/errors/4cac969039e2eca6.
Report an issue: GitHub.