apache/rocketmq · error · RemotingCommandException

Failed tp get max offset in queue

Error message

Failed tp get max offset in queue

What it means

PullMessageProcessor offset-reset path: when a reset offset is pending (queryThenEraseResetOffset hit), it fills GetMessageResult.maxOffset via getMaxOffsetInQueue; ConsumeQueueException is wrapped as RemotingCommandException. Note the message itself contains a typo ('Failed tp get') — search for the exact misspelling when grepping logs.

Source

Thrown at broker/src/main/java/org/apache/rocketmq/broker/processor/PullMessageProcessor.java:550

        }

        final boolean useResetOffsetFeature = brokerController.getBrokerConfig().isUseServerSideResetOffset();
        String topic = requestHeader.getTopic();
        String liteTopic = requestHeader.getLiteTopic();
        String group = requestHeader.getConsumerGroup();
        int queueId = requestHeader.getQueueId();
        Long resetOffset = brokerController.getConsumerOffsetManager().queryThenEraseResetOffset(topic, group, queueId);

        GetMessageResult getMessageResult = null;
        if (useResetOffsetFeature && null != resetOffset) {
            getMessageResult = new GetMessageResult();
            getMessageResult.setStatus(GetMessageStatus.OFFSET_RESET);
            getMessageResult.setNextBeginOffset(resetOffset);
            getMessageResult.setMinOffset(messageStore.getMinOffsetInQueue(topic, queueId));
            try {
                getMessageResult.setMaxOffset(messageStore.getMaxOffsetInQueue(topic, queueId));
            } catch (ConsumeQueueException e) {
                throw new RemotingCommandException("Failed tp get max offset in queue", e);
            }
            getMessageResult.setSuggestPullingFromSlave(false);
        } else {
            long broadcastInitOffset = queryBroadcastPullInitOffset(topic, group, queueId, requestHeader, channel);
            if (broadcastInitOffset >= 0) {
                getMessageResult = new GetMessageResult();
                getMessageResult.setStatus(GetMessageStatus.OFFSET_RESET);
                getMessageResult.setNextBeginOffset(broadcastInitOffset);
            } else {
                SubscriptionData finalSubscriptionData = subscriptionData;
                RemotingCommand finalResponse = response;
                String storeTopic = topic;
                if (StringUtils.isNotBlank(liteTopic)) {
                    storeTopic = LiteUtil.toLmqName(topic, liteTopic);
                }
                messageStore.getMessageAsync(group, storeTopic, queueId, requestHeader.getQueueOffset(),
                        requestHeader.getMaxMsgNums(), messageFilter)
                    .thenApply(result -> {

View on GitHub (pinned to 293f588571)

Solutions

  1. Let the broker finish loading its store before issuing offset resets and letting consumers pull.
  2. Check the wrapped ConsumeQueueException in broker.log for the failing topic/queue.
  3. Repair consume queues/disk; after store is healthy, re-issue the reset (the erased reset offset must be set again).
Defensive patterns

Strategy: retry

Try / catch

catch (RemotingCommandException e) { if (e.getMessage().contains("Failed tp get max offset")) { // note typo in broker message
    reissueResetOffsetAndRetryPull(); } else throw e; }

Prevention

When it happens

Trigger: A pull arrives for a group/queue with a pending reset offset (issued via resetOffset API) while the consume queue for that queue cannot be read.

Common situations: Ops run resetOffsetByTime/Id immediately after broker restart with store still loading; corrupt consume queue on the target queue; RocksDB consume queue errors.

Related errors


AI-assisted analysis of apache/rocketmq@293f588571 (2026-08-14). Data as JSON: /api/errors/03a862a0ccaedaa2. Report an issue: GitHub.