apache/pulsar · error · PulsarClientException.InvalidMessageException
Cannot handle messages with null messages
Error message
Cannot handle messages with null messages
What it means
validateMessages(Messages<?>) rejects a null Messages collection with InvalidMessageException 'Cannot handle messages with null messages' before iterating elements. It is used by the batch-acknowledgment path consumer.acknowledge(Messages), so a null Messages object is rejected up front as a caller bug.
Source
Thrown at pulsar-client/src/main/java/org/apache/pulsar/client/impl/ConsumerBase.java:449
private static void validateMessageId(MessageId messageId) throws PulsarClientException {
if (messageId == null) {
throw new PulsarClientException.InvalidMessageException("Cannot handle message with null messageId");
}
}
private static void validateMessageIds(List<MessageId> messageIdList) throws PulsarClientException {
if (messageIdList == null) {
throw new PulsarClientException.InvalidMessageException("Cannot handle messages with null messageIdList");
}
for (MessageId messageId : messageIdList) {
validateMessageId(messageId);
}
}
private static void validateMessages(Messages<?> messages) throws PulsarClientException {
if (messages == null) {
throw new PulsarClientException.InvalidMessageException("Cannot handle messages with null messages");
}
for (Message<?> message : messages) {
validateMessageId(message);
}
}
@Override
public void acknowledge(Message<?> message) throws PulsarClientException {
validateMessageId(message);
acknowledge(message.getMessageId());
}
@Override
public void acknowledge(MessageId messageId) throws PulsarClientException {
validateMessageId(messageId);
try {
acknowledgeAsync(messageId).get();
} catch (InterruptedException e) {
Thread.currentThread().interrupt();View on GitHub (pinned to 820761864e)
Solutions
- Null-check the Messages object before calling acknowledge(Messages)
- Ensure batchReceive() results are captured and validated before acking
- Return an empty Messages instance instead of null from wrapper methods
Example fix
// before
consumer.acknowledge(pendingBatch); // may be null
// after
if (pendingBatch != null) {
consumer.acknowledge(pendingBatch);
} Defensive patterns
Strategy: validation
Validate before calling
if (messages == null) {
return; // or throw IllegalArgumentException
} Type guard
boolean isAckableBatch(Messages<?> msgs) {
return msgs != null;
} Try / catch
try {
consumer.acknowledge(messages);
} catch (PulsarClientException.InvalidMessageException e) {
log.warn("Invalid messages collection for ack: {}", e.getMessage());
} Prevention
- Always capture and check batchReceive()/batchReceiveAsync() results before acking
- Assign Messages variables in all code branches or default to an empty Messages instance
- Centralize batch ack in one helper that performs the null check
When it happens
Trigger: Calling consumer.acknowledge((Messages<?>) null), typically when the Messages came from batchReceive() that was short-circuited, or a wrapper method forwards a null result.
Common situations: Storing the result of batchReceiveAsync().get() where an exception path yields null; conditional batch processing where the Messages variable is only assigned in one branch.
Related errors
- Cannot handle messages with null messageIdList
- Non-null message is required
- Cannot handle message with null messageId
- isDuplicated cannot accept
- tlsPolicy purpose and policy must not be null
AI-assisted analysis of apache/pulsar@820761864e (2026-09-06).
Data as JSON: /api/errors/7572669a22f92b64.
Report an issue: GitHub.