{"record":{"id":"4a3753b147d2d52e","repo":"apache/rocketmq","slug":"failed-to-get-max-offset","errorCode":null,"errorMessage":"Failed to get max offset","messagePattern":"Failed to get max offset","errorType":"exception","errorClass":"RemotingCommandException","httpStatus":null,"severity":"error","filePath":"broker/src/main/java/org/apache/rocketmq/broker/processor/AckMessageProcessor.java","lineNumber":155,"sourceCode":"                String errorInfo = String.format(\"queueId[%d] is illegal, topic:[%s] topicConfig.readQueueNums:[%d] consumer:[%s]\",\n                    requestHeader.getQueueId(), requestHeader.getTopic(), topicConfig.getReadQueueNums(), channel.remoteAddress());\n                POP_LOGGER.warn(errorInfo);\n                response.setCode(ResponseCode.MESSAGE_ILLEGAL);\n                response.setRemark(errorInfo);\n                return response;\n            }\n\n            RemotingCommand ackLiteResponse = ackLite(requestHeader, null, response, channel);\n            if (ackLiteResponse != null) {\n                return ackLiteResponse;\n            }\n\n            long minOffset = this.brokerController.getMessageStore().getMinOffsetInQueue(requestHeader.getTopic(), requestHeader.getQueueId());\n            long maxOffset;\n            try {\n                maxOffset = this.brokerController.getMessageStore().getMaxOffsetInQueue(requestHeader.getTopic(), requestHeader.getQueueId());\n            } catch (ConsumeQueueException e) {\n                throw new RemotingCommandException(\"Failed to get max offset\", e);\n            }\n            if (requestHeader.getOffset() < minOffset || requestHeader.getOffset() > maxOffset) {\n                String errorInfo = String.format(\"offset is illegal, key:%s@%d, commit:%d, store:%d~%d\",\n                    requestHeader.getTopic(), requestHeader.getQueueId(), requestHeader.getOffset(), minOffset, maxOffset);\n                POP_LOGGER.warn(errorInfo);\n                response.setCode(ResponseCode.NO_MESSAGE);\n                response.setRemark(errorInfo);\n                return response;\n            }\n            if (brokerController.getBrokerConfig().isPopConsumerKVServiceEnable()) {\n                appendAckNew(requestHeader, null, response, channel, null);\n            } else {\n                appendAck(requestHeader, null, response, channel, null);\n            }\n        } else if (request.getCode() == RequestCode.BATCH_ACK_MESSAGE) {\n            if (request.getBody() != null) {\n                reqBody = BatchAckMessageRequestBody.decode(request.getBody(), BatchAckMessageRequestBody.class);\n            }","sourceCodeStart":137,"sourceCodeEnd":173,"githubUrl":"https://github.com/apache/rocketmq/blob/293f5885719fc4aa3619446a1900f58ccfcfdd29/broker/src/main/java/org/apache/rocketmq/broker/processor/AckMessageProcessor.java#L137-L173","documentation":"AckMessageProcessor's single-ack path (used for pop consumers) validates the acked offset against [minOffset, maxOffset]; the max offset comes from messageStore.getMaxOffsetInQueue(), whose checked ConsumeQueueException is wrapped as RemotingCommandException('Failed to get max offset'). The ack request fails at the store layer before offset-legality checks or commit logic run.","triggerScenarios":"A pop consumer sending an AckMessage request for a topic/queue whose consume queue read throws — queue deleted (topic deleted concurrently), consume queue files corrupt, or store shutting down.","commonSituations":"Acks arriving right as a topic is deleted or migrated; store recovery/replay in progress; disk corruption on the consumeq directory.","solutions":["Check broker logs for the root ConsumeQueueException and affected topic/queueId","Confirm the topic and queue still exist on this broker (deleted queues cannot be acked; pop messages from a revived queue will retry/expire via the revive mechanism)","If store corruption is indicated, restart the broker to trigger consume-queue recovery, then let consumers re-ack","Retry acking after the broker is healthy; pop retries will redeliver un-acked messages"],"exampleFix":null,"handlingStrategy":"retry","validationCode":null,"typeGuard":null,"tryCatchPattern":"try {\n    popConsumer.ack(msg);\n} catch (Exception e) {\n    Throwable real = ExceptionUtils.getRealException(e);\n    if (real instanceof RemotingCommandException) {\n        // transient store failure: wait for broker recovery; pop revive will redeliver\n    }\n}","preventionTips":["Let pop retry/revive handle un-acked messages instead of hammering ack retries against a failing store","Monitor broker ConsumeQueueException logs and fix store health promptly","Avoid deleting topics while pop consumers still hold in-flight messages"],"tags":["broker","pop-consumer","ack","consume-queue","rocketmq"],"backgroundTag":null,"analyzedSha":"293f5885719fc4aa3619446a1900f58ccfcfdd29","analyzedAt":"2026-08-14T11:50:13.822Z","schemaVersion":2},"datasetVersion":"2026-08-15T22:17:37.221Z"}