apache/rocketmq · error · RemotingCommandException

Failed to get max offset in queue or iterate in queue

Error message

Failed to get max offset in queue or iterate in queue

What it means

NotificationProcessor (pop notification/long-polling) iterates consume queues to decide whether data is available; any ConsumeQueueException or RocksDBException from getMaxOffsetInQueue or the queue iterator is wrapped as RemotingCommandException and fails the notification request.

Source

Thrown at broker/src/main/java/org/apache/rocketmq/broker/processor/NotificationProcessor.java:292

                    iterator = queue.iterateFrom(offset, 32);
                    if (iterator != null) {
                        while (iterator.hasNext()) {
                            CqUnit cqUnit = iterator.next();
                            if (messageFilter.isMatchedByConsumeQueue(cqUnit.getValidTagsCodeAsLong(), cqUnit.getCqExtUnit())) {
                                return true;
                            }
                        }
                        return false;
                    }
                } finally {
                    if (iterator != null) {
                        iterator.release();
                    }
                }
            }
            return restNum > 0;
        } catch (ConsumeQueueException | RocksDBException e) {
            throw new RemotingCommandException("Failed to get max offset in queue or iterate in queue", e);
        }
    }

    private long getPopOffset(String topic, String cid, int queueId) {
        long offset = this.brokerController.getConsumerOffsetManager().queryOffset(cid, topic, queueId);
        if (offset < 0) {
            offset = this.brokerController.getMessageStore().getMinOffsetInQueue(topic, queueId);
        }

        long bufferOffset;
        if (brokerController.getBrokerConfig().isPopConsumerKVServiceEnable()) {
            bufferOffset = this.brokerController.getConsumerOffsetManager().queryPullOffset(cid, topic, queueId);
        } else {
            bufferOffset = this.brokerController.getPopMessageProcessor()
                .getPopBufferMergeService().getLatestOffset(topic, cid, queueId);
        }

        return bufferOffset < 0L ? offset : Math.max(bufferOffset, offset);

View on GitHub (pinned to 293f588571)

Solutions

  1. Read the wrapped cause in broker.log (ConsumeQueueException vs RocksDBException) to identify the backend at fault.
  2. For RocksDB, check/repair the RocksDB directory and disk; ensure no two broker processes share it.
  3. Avoid deleting topics with active pop consumers; drain consumers first.
  4. Restart broker after store recovery; notifications resume when queues are readable.
Defensive patterns

Strategy: try-catch

Try / catch

catch (RemotingCommandException e) { Throwable c = e.getCause(); if (c instanceof ConsumeQueueException || c instanceof RocksDBException) { logAndPageOnCallIfHealthy(); } else throw e; }

Prevention

When it happens

Trigger: Pop notification request for a topic whose consume queue or RocksDB store raises an exception during iteration — corrupt store, deleted queue mid-iteration, RocksDB backend failure.

Common situations: RocksDB consume-queue store (enableRocksDBStore) on failing disk; topic deleted/queues changed while notification long-polling holds an iterator; store not fully recovered.

Related errors


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