{"record":{"id":"601491ca493a0183","repo":"apache/rocketmq","slug":"failed-to-get-max-offset-in-queue-601491","errorCode":null,"errorMessage":"Failed to get max offset in queue","messagePattern":"Failed to get max offset in queue","errorType":"exception","errorClass":"RemotingCommandException","httpStatus":null,"severity":"error","filePath":"broker/src/main/java/org/apache/rocketmq/broker/processor/AckMessageProcessor.java","lineNumber":239,"sourceCode":"            ackMsg = new AckMsg();\n            ackCount = 1;\n        } else {\n            // batch ack\n            consumeGroup = batchAck.getConsumerGroup();\n            topic = ExtraInfoUtil.getRealTopic(batchAck.getTopic(), batchAck.getConsumerGroup(), batchAck.getRetry());\n            qId = batchAck.getQueueId();\n            rqId = batchAck.getReviveQueueId();\n            startOffset = batchAck.getStartOffset();\n            ackOffset = -1;\n            popTime = batchAck.getPopTime();\n            invisibleTime = batchAck.getInvisibleTime();\n\n            long minOffset = this.brokerController.getMessageStore().getMinOffsetInQueue(topic, qId);\n            long maxOffset;\n            try {\n                maxOffset = this.brokerController.getMessageStore().getMaxOffsetInQueue(topic, qId);\n            } catch (ConsumeQueueException e) {\n                throw new RemotingCommandException(\"Failed to get max offset in queue\", e);\n            }\n            if (minOffset == -1 || maxOffset == -1) {\n                POP_LOGGER.error(\"Illegal topic or queue found when batch ack {}\", batchAck);\n                return;\n            }\n\n            BatchAckMsg batchAckMsg = new BatchAckMsg();\n            BitSet bitSet = batchAck.getBitSet();\n            for (int i = bitSet.nextSetBit(0); i >= 0; i = bitSet.nextSetBit(i + 1)) {\n                if (i == Integer.MAX_VALUE) {\n                    break;\n                }\n                long offset = startOffset + i;\n                if (offset < minOffset || offset > maxOffset) {\n                    continue;\n                }\n                if (rqId == KeyBuilder.POP_ORDER_REVIVE_QUEUE) {\n                    ackOrderly(topic, consumeGroup, qId, offset, popTime, invisibleTime, channel, response);","sourceCodeStart":221,"sourceCodeEnd":257,"githubUrl":"https://github.com/apache/rocketmq/blob/293f5885719fc4aa3619446a1900f58ccfcfdd29/broker/src/main/java/org/apache/rocketmq/broker/processor/AckMessageProcessor.java#L221-L257","documentation":"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.","triggerScenarios":"BatchAckMessage requests from pop consumers when the target topic/queue's consume queue read fails (queue removed mid-flight, corrupt consumeq files, store closing).","commonSituations":"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.","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"],"exampleFix":null,"handlingStrategy":"retry","validationCode":null,"typeGuard":null,"tryCatchPattern":"try {\n    popConsumer.ack(batch);\n} catch (Exception e) {\n    Throwable real = ExceptionUtils.getRealException(e);\n    if (real instanceof RemotingCommandException) { /* whole batch aborted; rely on pop redelivery after store recovery */ }\n}","preventionTips":["Verify queue existence before batch acking after topic changes","Treat broker store errors as a signal to pause acking, not to retry immediately"],"tags":["broker","pop-consumer","batch-ack","consume-queue","rocketmq"],"backgroundTag":null,"analyzedSha":"293f5885719fc4aa3619446a1900f58ccfcfdd29","analyzedAt":"2026-08-14T11:50:13.822Z","schemaVersion":2},"datasetVersion":"2026-08-15T17:31:12.345Z"}