{"record":{"id":"2d04a1e893f78489","repo":"apache/rocketmq","slug":"failed-to-get-max-offset-2d04a1","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/AdminBrokerProcessor.java","lineNumber":2761,"sourceCode":"                        && this.brokerController.getConsumerManager().findSubscriptionDataCount(group) > 0) {\n                        LOGGER.warn(\n                            \"AdminBrokerProcessor#fetchAllConsumeStatsInBroker: topic does not exist in consumer \"\n                                + \"group's subscription, topic={}, consumer group={}\", topic, group);\n                        continue;\n                    }\n                }\n\n                for (int i = 0; i < topicConfig.getWriteQueueNums(); i++) {\n                    MessageQueue mq = new MessageQueue();\n                    mq.setTopic(topic);\n                    mq.setBrokerName(this.brokerController.getBrokerConfig().getBrokerName());\n                    mq.setQueueId(i);\n                    OffsetWrapper offsetWrapper = new OffsetWrapper();\n                    long brokerOffset;\n                    try {\n                        brokerOffset = this.brokerController.getMessageStore().getMaxOffsetInQueue(topic, i);\n                    } catch (ConsumeQueueException e) {\n                        throw new RemotingCommandException(\"Failed to get max offset\", e);\n                    }\n                    if (brokerOffset < 0) {\n                        brokerOffset = 0;\n                    }\n                    long consumerOffset = this.brokerController.getConsumerOffsetManager().queryOffset(\n                        group,\n                        topic,\n                        i);\n                    if (consumerOffset < 0)\n                        consumerOffset = 0;\n\n                    offsetWrapper.setBrokerOffset(brokerOffset);\n                    offsetWrapper.setConsumerOffset(consumerOffset);\n\n                    long timeOffset = consumerOffset - 1;\n                    if (timeOffset >= 0) {\n                        long lastTimestamp = this.brokerController.getMessageStore().getMessageStoreTimeStamp(topic, i, timeOffset);\n                        if (lastTimestamp > 0) {","sourceCodeStart":2743,"sourceCodeEnd":2779,"githubUrl":"https://github.com/apache/rocketmq/blob/293f5885719fc4aa3619446a1900f58ccfcfdd29/broker/src/main/java/org/apache/rocketmq/broker/processor/AdminBrokerProcessor.java#L2743-L2779","documentation":"Thrown while a broker admin command (consume-stats / topic-offset enumeration in AdminBrokerProcessor) walks every write queue of a topic and calls MessageStore.getMaxOffsetInQueue(topic, i). The underlying getMaxOffsetInQueue declares ConsumeQueueException, and this wrapper converts it into a RemotingCommandException that fails the whole admin RPC. It means the broker could not read a consume queue to compute the max offset for at least one queue.","triggerScenarios":"Calling GET_CONSUME_STATS / getAllConsumeOffset-style admin APIs for a topic whose ConsumeQueue is missing, corrupt, or unreadable; ConsumeQueue store backend (RocksDB) errors; queue files deleted while store is loading or after an unclean shutdown.","commonSituations":"Broker restarted after crash with damaged consume queue files; RocksDB consume queue enabled (enableRocksDBStore) and its directory is corrupted or on a failing disk; topic queues shrunk/deleted concurrently with the stats query.","solutions":["Check broker.log for the wrapped ConsumeQueueException cause (store layer) — it names the exact topic/queue and underlying IO error.","Verify consume queue directory integrity for the affected topic (store/consumequeue/<topic>) and disk health.","If the store failed to load a queue, restart the broker after fixing/recovering the store files; the admin call then succeeds.","As a workaround, query offsets per-queue or use mqAdmin consumerProgress on a healthy replica/slave broker."],"exampleFix":null,"handlingStrategy":"retry","validationCode":"// broker health gate before admin offset queries\nboolean storeOk = brokerController.getMessageStore() instanceof DefaultMessageStore\n    && !((DefaultMessageStore) brokerController.getMessageStore()).isShutdown();","typeGuard":null,"tryCatchPattern":"catch (RemotingCommandException e) { if (e.getCause() instanceof ConsumeQueueException) { /* transient store issue: backoff and retry on another broker */ } throw e; }","preventionTips":["Run consume-stats against a fully started broker (wait for store load completion).","Monitor disk health and RocksDB consume-queue directories.","Do not delete/resize topics while admin offset enumeration is in progress."],"tags":["rocketmq","broker","consume-queue","offset","admin-api","storage"],"backgroundTag":null,"analyzedSha":"293f5885719fc4aa3619446a1900f58ccfcfdd29","analyzedAt":"2026-08-14T11:50:13.822Z","schemaVersion":2},"datasetVersion":"2026-08-15T22:17:37.221Z"}