apache/pulsar · error · java.lang.IllegalStateException

Empty message batch

Error message

Empty message batch

What it means

Thrown by MessagesV5.lastId() when the batch contains no messages. The library cannot return a meaningful last message id from an empty collection, so it fails fast with IllegalStateException. Callers must check size/emptiness before querying batch boundary ids.

Source

Thrown at pulsar-client-v5/src/main/java/org/apache/pulsar/client/impl/v5/MessagesV5.java:46

 * Simple implementation of Messages wrapping a list of Message instances.
 */
final class MessagesV5<T> implements Messages<T> {

    private final List<Message<T>> messages;

    MessagesV5(List<Message<T>> messages) {
        this.messages = messages;
    }

    @Override
    public int count() {
        return messages.size();
    }

    @Override
    public MessageId lastId() {
        if (messages.isEmpty()) {
            throw new IllegalStateException("Empty message batch");
        }
        return messages.get((messages.size() - 1)).id();
    }

    @Override
    public Iterator<Message<T>> iterator() {
        return messages.iterator();
    }
}

View on GitHub (pinned to 820761864e)

Solutions

  1. Check messages.isEmpty() (or size() > 0) before calling lastId()
  2. Guard by tracking whether any messages were received and skip lastId() when none were
  3. If lastId is used for cumulative acks, only ack when the batch is non-empty

Example fix

// before
MessageId last = batch.lastId();
// after
if (batch.size() > 0) {
    MessageId last = batch.lastId();
}
Defensive patterns

Strategy: validation

Validate before calling

if (batch == null || batch.size() == 0) { skipLastId(); } else { batch.lastId(); }

Prevention

When it happens

Trigger: Calling lastId() on a MessagesV5 instance built with no messages, e.g. after filtering out every message or constructing an empty MessagesV5 via its builder/factory.

Common situations: A consumer received no messages but code still tries to inspect the batch's last id for cursor/cumulative-ack bookkeeping; a loop that drains a queue into a batch ends up empty.

Related errors


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