apache/rocketmq · error · RuntimeException

Can't accept data with unmatched scope %s != %s

Error message

Can't accept data with unmatched scope %s != %s

What it means

Non-force update of topic-queue mapping requires the new detail's scope to equal the stored one; a different scope (the namespace/domain a mapping belongs to) is rejected with RuntimeException. Scope is part of the mapping identity and must stay stable across updates.

Source

Thrown at broker/src/main/java/org/apache/rocketmq/broker/topic/TopicQueueMappingManager.java:109

                topicQueueMappingTable.put(newDetail.getTopic(), newDetail);
                updated = true;
                return;
            }
            if (force) {
                //bakeup the old items
                oldDetail.getHostedQueues().forEach((queueId, items) -> {
                    newDetail.getHostedQueues().putIfAbsent(queueId, items);
                });
                topicQueueMappingTable.put(newDetail.getTopic(), newDetail);
                updated = true;
                return;
            }
            //do more check
            if (newDetail.getEpoch() < oldDetail.getEpoch()) {
                throw new RuntimeException(String.format("Can't accept data with small epoch %d < %d", newDetail.getEpoch(), oldDetail.getEpoch()));
            }
            if (!newDetail.getScope().equals(oldDetail.getScope())) {
                throw new RuntimeException(String.format("Can't accept data with unmatched scope %s != %s", newDetail.getScope(), oldDetail.getScope()));
            }
            boolean epochEqual = newDetail.getEpoch() == oldDetail.getEpoch();
            for (Integer globalId : oldDetail.getHostedQueues().keySet()) {
                List<LogicQueueMappingItem> oldItems = oldDetail.getHostedQueues().get(globalId);
                List<LogicQueueMappingItem> newItems = newDetail.getHostedQueues().get(globalId);
                if (newItems == null) {
                    if (epochEqual) {
                        throw new RuntimeException("Cannot accept equal epoch with null data");
                    } else {
                        newDetail.getHostedQueues().put(globalId, oldItems);
                    }
                } else {
                    TopicQueueMappingUtils.makeSureLogicQueueMappingItemImmutable(oldItems, newItems, epochEqual, isClean);
                }
            }
            topicQueueMappingTable.put(newDetail.getTopic(), newDetail);
            updated = true;
        }  finally {

View on GitHub (pinned to 293f588571)

Solutions

  1. Read the existing mapping's scope and submit the update with the identical scope value.
  2. Standardize which scope (global vs cluster/domain) manages this topic; don't interleave commands with different scope settings.
  3. If a genuine scope migration is needed, do it as a controlled migration (force path / recreate mapping), not an in-place update.
Defensive patterns

Strategy: validation

Validate before calling

TopicQueueMappingDetail old = manager.queryTopicQueueMapping(topic);
if (old != null && !newDetail.getScope().equals(old.getScope())) {
    newDetail.setScope(old.getScope()); // scope is immutable across updates
}

Type guard

boolean scopeMatches(TopicQueueMappingDetail oldD, TopicQueueMappingDetail newD) {
    return oldD == null || oldD.getScope().equals(newD.getScope());
}

Try / catch

catch (RuntimeException e) { if (e.getMessage().contains("unmatched scope")) { adoptStoredScope(); resubmit(); } else throw e; }

Prevention

When it happens

Trigger: updateTopicQueueMapping submitting detail with scope 'clusterA' while stored detail has scope 'domainA' (or full vs partial scope names) with equal-or-greater epoch.

Common situations: Mixing global-scope and cluster-scope mapping commands; tools upgraded between versions that change default scope strings; copying mapping config across environments with different scope configuration.

Related errors


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