LMAX-Exchange/disruptor · error · IllegalArgumentException

maxBatchSize must be greater than 0

Error message

maxBatchSize must be greater than 0

What it means

Thrown by the BatchEventProcessor constructor when maxBatchSize is less than 1. The processor pre-computes batchLimitOffset = maxBatchSize - 1 to cap how many events it claims per batch; a maxBatchSize of 0 or negative makes that offset meaningless and would break batch iteration.

Source

Thrown at src/main/java/com/lmax/disruptor/BatchEventProcessor.java:61

    private final Sequence sequence = new Sequence(Sequencer.INITIAL_CURSOR_VALUE);
    private final RewindHandler rewindHandler;
    private int retriesAttempted = 0;

    BatchEventProcessor(
            final DataProvider<T> dataProvider,
            final SequenceBarrier sequenceBarrier,
            final EventHandlerBase<? super T> eventHandler,
            final int maxBatchSize,
            final BatchRewindStrategy batchRewindStrategy
    )
    {
        this.dataProvider = dataProvider;
        this.sequenceBarrier = sequenceBarrier;
        this.eventHandler = eventHandler;

        if (maxBatchSize < 1)
        {
            throw new IllegalArgumentException("maxBatchSize must be greater than 0");
        }
        this.batchLimitOffset = maxBatchSize - 1;

        this.rewindHandler = eventHandler instanceof RewindableEventHandler
                ? new TryRewindHandler(batchRewindStrategy)
                : new NoRewindHandler();
    }

    @Override
    public Sequence getSequence()
    {
        return sequence;
    }

    @Override
    public void halt()
    {
        running.set(HALTED);

View on GitHub (pinned to c871ca4982)

Solutions

  1. Pass a maxBatchSize >= 1 (the default is typically the full buffer size when batching is unlimited).
  2. If the value comes from config, validate it at load time and apply a sane minimum (e.g. Math.max(1, configured)).
  3. Check you are not passing an already-decremented offset — the API expects the size itself.

Example fix

// before
BatchEventProcessorBuilder builder = new BatchEventProcessorBuilder();
builder.maxBatchSize(config.getBatchLimit() - 1); // config returns 1 -> 0

// after
builder.maxBatchSize(Math.max(1, config.getBatchLimit()));
Defensive patterns

Strategy: validation

Validate before calling

int maxBatch = Math.max(1, config.getMaxBatchSize());
builder.maxBatchSize(maxBatch);

Prevention

When it happens

Trigger: Building a BatchEventProcessor (directly or via BatchEventProcessorBuilder with maxBatchSize(...)) and passing 0 or a negative value, e.g. builder.maxBatchSize(0).build(...).

Common situations: maxBatchSize is made configurable and defaults to 0 when unset; it is computed from a batch-limit property parsed incorrectly; copy-paste from code where the parameter meant 'offset' rather than 'size' (off-by-one: passing maxBatchSize - 1).

Related errors


AI-assisted analysis of LMAX-Exchange/disruptor@c871ca4982 (2026-08-14). Data as JSON: /api/errors/42e7e818d5c7e2f8. Report an issue: GitHub.