apache/rocketmq · error · RemotingCommandException
Failed to get max consume offset
Error message
Failed to get max consume offset
What it means
ChangeInvisibleTimeProcessor (pop consumer ack-delay extension) validates the pop offset: it reads MessageStore.getMaxOffsetInQueue for the topic/queue and wraps any ConsumeQueueException in RemotingCommandException, failing the CHANGE_INVISIBLE_TIME request.
Source
Thrown at broker/src/main/java/org/apache/rocketmq/broker/processor/ChangeInvisibleTimeProcessor.java:134
String errorInfo = String.format("queueId[%d] is illegal, topic:[%s] topicConfig.readQueueNums:[%d] consumer:[%s]",
requestHeader.getQueueId(), requestHeader.getTopic(), topicConfig.getReadQueueNums(), channel.remoteAddress());
POP_LOGGER.warn(errorInfo);
response.setCode(ResponseCode.MESSAGE_ILLEGAL);
response.setRemark(errorInfo);
return CompletableFuture.completedFuture(response);
}
CompletableFuture<RemotingCommand> future = processChangeInvisibleTimeForLite(requestHeader, response, responseHeader);
if (future != null) {
return future;
}
long minOffset = this.brokerController.getMessageStore().getMinOffsetInQueue(requestHeader.getTopic(), requestHeader.getQueueId());
long maxOffset;
try {
maxOffset = this.brokerController.getMessageStore().getMaxOffsetInQueue(requestHeader.getTopic(), requestHeader.getQueueId());
} catch (ConsumeQueueException e) {
throw new RemotingCommandException("Failed to get max consume offset", e);
}
if (requestHeader.getOffset() < minOffset || requestHeader.getOffset() >= maxOffset) {
response.setCode(ResponseCode.NO_MESSAGE);
return CompletableFuture.completedFuture(response);
}
String[] extraInfo = ExtraInfoUtil.split(requestHeader.getExtraInfo());
if (brokerController.getBrokerConfig().isPopConsumerKVServiceEnable()) {
if (ExtraInfoUtil.isOrder(extraInfo)) {
return this.processChangeInvisibleTimeForOrderNew(
requestHeader, extraInfo, response, responseHeader);
}
try {
long current = System.currentTimeMillis();
brokerController.getPopConsumerService().changeInvisibilityDuration(
ExtraInfoUtil.getPopTime(extraInfo), ExtraInfoUtil.getInvisibleTime(extraInfo), current,
requestHeader.getInvisibleTime(), requestHeader.getConsumerGroup(), requestHeader.getTopic(),
requestHeader.getQueueId(), requestHeader.getOffset(), requestHeader.isSuspend());View on GitHub (pinned to 293f588571)
Solutions
- Check broker.log for the underlying ConsumeQueueException and failing topic/queueId.
- Ensure the topic still exists and its consume queues are healthy (mqAdmin topicStatus).
- Retry after the broker finishes loading; if queues are corrupt, restore/rebuild them.
- Avoid issuing changeInvisibleTime for messages whose topic has been deleted.
Defensive patterns
Strategy: retry
Try / catch
catch (RemotingCommandException e) { if (e.getCause() instanceof ConsumeQueueException) { scheduleChangeInvisibleTimeRetryWithBackoff(); return; } throw e; } Prevention
- Skip changeInvisibleTime for topics being deleted.
- Keep pop retry topics' consume queues healthy; alert on ConsumeQueueException in broker logs.
When it happens
Trigger: Pop consumer calls ChangeInvisibleTime for a message whose consume queue cannot be read — corrupt queue files, store still loading, RocksDB consume queue failure, or topic deleted while pop requests are in flight.
Common situations: Long pop-invisible-time messages being extended after the topic was deleted/recreated; broker recovered with damaged consume queues; store not fully initialized at request time.
Related errors
- Failed to get max offset in queue or iterate in queue
- Failed to get max offset in queue
- Failed to get max offset
- Failed to get max offset in queue
- Failed to ack message
AI-assisted analysis of apache/rocketmq@293f588571 (2026-08-14).
Data as JSON: /api/errors/a5869dd687d19167.
Report an issue: GitHub.