{"record":{"id":"b355513866900a3c","repo":"apache/rocketmq","slug":"failed-to-get-max-offset-in-queue-b35551","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/AdminBrokerProcessor.java","lineNumber":1362,"sourceCode":"    }\n\n    private RemotingCommand getMaxOffset(ChannelHandlerContext ctx,\n        RemotingCommand request) throws RemotingCommandException {\n        final RemotingCommand response = RemotingCommand.createResponseCommand(GetMaxOffsetResponseHeader.class);\n        final GetMaxOffsetResponseHeader responseHeader = (GetMaxOffsetResponseHeader) response.readCustomHeader();\n        final GetMaxOffsetRequestHeader requestHeader = request.decodeCommandCustomHeader(GetMaxOffsetRequestHeader.class);\n\n        TopicQueueMappingContext mappingContext = this.brokerController.getTopicQueueMappingManager().buildTopicQueueMappingContext(requestHeader);\n        RemotingCommand rewriteResult = rewriteRequestForStaticTopic(requestHeader, mappingContext);\n        if (rewriteResult != null) {\n            return rewriteResult;\n        }\n\n        try {\n            long offset = this.brokerController.getMessageStore().getMaxOffsetInQueue(requestHeader.getTopic(), requestHeader.getQueueId());\n            responseHeader.setOffset(offset);\n        } catch (ConsumeQueueException e) {\n            throw new RemotingCommandException(\"Failed to get max offset in queue\", e);\n        }\n        response.setCode(ResponseCode.SUCCESS);\n        response.setRemark(null);\n        return response;\n    }\n\n    private CompletableFuture<RpcResponse> handleGetMinOffsetForStaticTopic(RpcRequest request,\n        TopicQueueMappingContext mappingContext) {\n        if (mappingContext.getMappingDetail() == null) {\n            return null;\n        }\n        TopicQueueMappingDetail mappingDetail = mappingContext.getMappingDetail();\n        if (!mappingContext.isLeader()) {\n            //this may not\n            return CompletableFuture.completedFuture(new RpcResponse(new RpcException(ResponseCode.NOT_LEADER_FOR_QUEUE,\n                String.format(\"%s-%d is not leader in broker %s, request code %d\", mappingContext.getTopic(), mappingContext.getGlobalId(), mappingDetail.getBname(), request.getCode()))));\n        }\n        GetMinOffsetRequestHeader requestHeader = (GetMinOffsetRequestHeader) request.getHeader();","sourceCodeStart":1344,"sourceCodeEnd":1380,"githubUrl":"https://github.com/apache/rocketmq/blob/293f5885719fc4aa3619446a1900f58ccfcfdd29/broker/src/main/java/org/apache/rocketmq/broker/processor/AdminBrokerProcessor.java#L1344-L1380","documentation":"AdminBrokerProcessor's handler for the GetMaxOffset request (requestCode GET_MAX_OFFSET) reads the queue's max offset via getMaxOffsetInQueue; the checked ConsumeQueueException is rethrown as RemotingCommandException('Failed to get max offset in queue'). For static (statically-mapped) topics this runs after rewriteRequestForStaticTopic has resolved the local queue, so the failure is purely the local store lookup.","triggerScenarios":"Client/admin calling QueryMaxOffset (e.g. DefaultMQAdminExt / consumer client maxOffset) for a topic+queueId whose consume queue read fails: nonexistent queueId, deleted topic, corrupt consumeq, or store closing.","commonSituations":"Clients querying max offset on a queueId beyond the topic's queue count; querying during topic deletion or broker shutdown; consume queue corruption after crash.","solutions":["Verify topic route and queue count (mqadmin topicRoute) and use a valid queueId","Check broker logs for the ConsumeQueueException root cause","If corruption is indicated, restart the broker to run store recovery for consume queues","Retry the query after the broker is fully started"],"exampleFix":null,"handlingStrategy":"validation","validationCode":"// client-side: validate queueId against the route before querying\nTopicRouteData route = mqAdminExt.examineTopicRouteInfo(topic);\nint maxQueue = route.getQueueDatas().stream().mapToInt(QueueData::getReadQueueNums).max().orElse(0);\nif (queueId < 0 || queueId >= maxQueue) throw new IllegalArgumentException(\"queueId out of range\");","typeGuard":null,"tryCatchPattern":"try {\n    long max = mqAdminExt.maxOffset(new MessageQueue(topic, brokerName, queueId));\n} catch (Exception e) {\n    Throwable real = ExceptionUtils.getRealException(e);\n    if (real instanceof RemotingCommandException) { /* store lookup failed: check broker logs, retry when healthy */ }\n}","preventionTips":["Always derive queueIds from the current topic route, never hard-code them","Retry offset queries after broker restart completes store recovery"],"tags":["broker","admin","max-offset","consume-queue","rocketmq"],"backgroundTag":null,"analyzedSha":"293f5885719fc4aa3619446a1900f58ccfcfdd29","analyzedAt":"2026-08-14T11:50:13.822Z","schemaVersion":2},"datasetVersion":"2026-08-15T22:17:37.221Z"}