apache/rocketmq · error · RemotingCommandException
Failed to get max offset in queue
Error message
Failed to get max offset in queue
What it means
AckMessageProcessor's batch-ack handling (ackLite/batch path) resolves the queue's max offset via getMaxOffsetInQueue(topic, qId) to sanity-check each acked offset; a ConsumeQueueException from that lookup is wrapped in RemotingCommandException('Failed to get max offset in queue'). The whole batch ack aborts — none of its offsets are committed.
Source
Thrown at broker/src/main/java/org/apache/rocketmq/broker/processor/AckMessageProcessor.java:239
ackMsg = new AckMsg();
ackCount = 1;
} else {
// batch ack
consumeGroup = batchAck.getConsumerGroup();
topic = ExtraInfoUtil.getRealTopic(batchAck.getTopic(), batchAck.getConsumerGroup(), batchAck.getRetry());
qId = batchAck.getQueueId();
rqId = batchAck.getReviveQueueId();
startOffset = batchAck.getStartOffset();
ackOffset = -1;
popTime = batchAck.getPopTime();
invisibleTime = batchAck.getInvisibleTime();
long minOffset = this.brokerController.getMessageStore().getMinOffsetInQueue(topic, qId);
long maxOffset;
try {
maxOffset = this.brokerController.getMessageStore().getMaxOffsetInQueue(topic, qId);
} catch (ConsumeQueueException e) {
throw new RemotingCommandException("Failed to get max offset in queue", e);
}
if (minOffset == -1 || maxOffset == -1) {
POP_LOGGER.error("Illegal topic or queue found when batch ack {}", batchAck);
return;
}
BatchAckMsg batchAckMsg = new BatchAckMsg();
BitSet bitSet = batchAck.getBitSet();
for (int i = bitSet.nextSetBit(0); i >= 0; i = bitSet.nextSetBit(i + 1)) {
if (i == Integer.MAX_VALUE) {
break;
}
long offset = startOffset + i;
if (offset < minOffset || offset > maxOffset) {
continue;
}
if (rqId == KeyBuilder.POP_ORDER_REVIVE_QUEUE) {
ackOrderly(topic, consumeGroup, qId, offset, popTime, invisibleTime, channel, response);View on GitHub (pinned to 293f588571)
Solutions
- Locate the underlying ConsumeQueueException cause in broker logs for the exact topic/queue
- Ensure the topic/queue still exists before clients batch-ack; removed queues should be skipped by clients
- Recover/rebuild consume queues via broker restart if files are corrupt
- After recovery, rely on pop retry/revive to redeliver the un-acked batch rather than resubmitting stale acks
Defensive patterns
Strategy: retry
Try / catch
try {
popConsumer.ack(batch);
} catch (Exception e) {
Throwable real = ExceptionUtils.getRealException(e);
if (real instanceof RemotingCommandException) { /* whole batch aborted; rely on pop redelivery after store recovery */ }
} Prevention
- Verify queue existence before batch acking after topic changes
- Treat broker store errors as a signal to pause acking, not to retry immediately
When it happens
Trigger: BatchAckMessage requests from pop consumers when the target topic/queue's consume queue read fails (queue removed mid-flight, corrupt consumeq files, store closing).
Common situations: Pop consumers with batch acking enabled acking against a topic being deleted or whose queue was trimmed; store in recovery; same corruption scenarios as the single-ack path but affecting the entire batch.
Related errors
- Failed to get max offset
- Failed to ack message
- Failed to get max consume offset
- Failed to get max offset in queue or iterate in queue
- Failed to get max offset in queue
AI-assisted analysis of apache/rocketmq@293f588571 (2026-08-14).
Data as JSON: /api/errors/601491ca493a0183.
Report an issue: GitHub.