LMAX-Exchange/disruptor · error · IllegalArgumentException
The ring buffer cannot accommodate
Error message
The ring buffer cannot accommodate {} it only has space for {} entities. What it means
Thrown by RingBuffer.checkBatchSizing during batch publishing when batchSize exceeds the ring buffer capacity. A batch publish claims batchSize consecutive slots; claiming more slots than the ring holds can never succeed (the publisher would have to wait for itself), so it is rejected up front instead of deadlocking.
Solutions
- Split the batch into chunks of at most ringBuffer.getBufferSize() and publish each chunk.
- Or increase the ring buffer size to at least the maximum batch size.
- Add a startup check: maxBatchSize <= ringBufferSize.
Example fix
// before
ringBuffer.publishEvents(translators, 0, translators.length); // 5000 into 1024 ring
// after
int chunk = ringBuffer.getBufferSize();
for (int i = 0; i < translators.length; i += chunk) {
int n = Math.min(chunk, translators.length - i);
ringBuffer.publishEvents(translators, i, n);
} Defensive patterns
Strategy: validation
Validate before calling
int capacity = ringBuffer.getBufferSize();
if (batchSize > capacity) {
for (int i = 0; i < items.size(); i += capacity) {
ringBuffer.publishEvents(translators, i, Math.min(capacity, items.size() - i));
}
return;
} Prevention
- Chunk all bulk publishes at ringBuffer.getBufferSize().
- Assert maxBatchSize <= ringBufferSize once at startup.
When it happens
Trigger: Calling publishEvents(translators, 0, 5000) on a 1024-entry ring buffer; any batch publish whose count argument is greater than ringBuffer.getBufferSize().
Common situations: Batch size from config outgrows a small ring (e.g. tests use bufferSize 8 while production batches are 100); bulk-loading code that publishes an entire list in one call; capacity tuned down for memory without revisiting batch size.
Related errors
- A batchSize of: with batchStatsAt of: will overrun the…
- Both batchStartsAt and batchSize must be positive but got…
- n must be > 0 and < bufferSize
- bufferSize must be a power of 2
- bufferSize must be a power of 2
AI-assisted analysis of LMAX-Exchange/disruptor@c871ca4982 (2026-08-14).
Data as JSON: /api/errors/0d4de3c27e600782.
Report an issue: GitHub.
Appendix: source
Thrown at src/main/java/com/lmax/disruptor/RingBuffer.java:908
{
return sequencer.remainingCapacity();
}
private void checkBounds(final EventTranslator<E>[] translators, final int batchStartsAt, final int batchSize)
{
checkBatchSizing(batchStartsAt, batchSize);
batchOverRuns(translators, batchStartsAt, batchSize);
}
private void checkBatchSizing(final int batchStartsAt, final int batchSize)
{
if (batchStartsAt < 0 || batchSize < 0)
{
throw new IllegalArgumentException("Both batchStartsAt and batchSize must be positive but got: batchStartsAt " + batchStartsAt + " and batchSize " + batchSize);
}
else if (batchSize > bufferSize)
{
throw new IllegalArgumentException("The ring buffer cannot accommodate " + batchSize + " it only has space for " + bufferSize + " entities.");
}
}
private <A> void checkBounds(final A[] arg0, final int batchStartsAt, final int batchSize)
{
checkBatchSizing(batchStartsAt, batchSize);
batchOverRuns(arg0, batchStartsAt, batchSize);
}
private <A, B> void checkBounds(final A[] arg0, final B[] arg1, final int batchStartsAt, final int batchSize)
{
checkBatchSizing(batchStartsAt, batchSize);
batchOverRuns(arg0, batchStartsAt, batchSize);
batchOverRuns(arg1, batchStartsAt, batchSize);
}
private <A, B, C> void checkBounds(
final A[] arg0, final B[] arg1, final C[] arg2, final int batchStartsAt, final int batchSize)View on GitHub (pinned to c871ca4982)