apache/pulsar · warning · IllegalArgumentException
Other MessageId not have topic
Error message
Other MessageId not have topic
What it means
During MultiMessageIdImpl.compareTo, every topic key in the current map must exist in the other map; if otherMap.get(topic) returns null it throws IllegalArgumentException('Other MessageId not have topic ' + topic). Even with equal sizes, the key sets can differ (e.g. re-partitioning renamed topics, or cursors built from different topic lists).
Source
Thrown at pulsar-client/src/main/java/org/apache/pulsar/client/impl/MultiMessageIdImpl.java:76
"expected MultiMessageIdImpl object. Got instance of " + o.getClass().getName());
}
MultiMessageIdImpl other = (MultiMessageIdImpl) o;
Map<String, MessageId> otherMap = other.getMap();
if ((map == null || map.isEmpty()) && (otherMap == null || otherMap.isEmpty())) {
return 0;
}
if (otherMap == null || map == null || otherMap.size() != map.size()) {
throw new IllegalArgumentException("Current size and other size not equals");
}
int result = 0;
for (Entry<String, MessageId> entry : map.entrySet()) {
MessageId otherMessage = otherMap.get(entry.getKey());
if (otherMessage == null) {
throw new IllegalArgumentException(
"Other MessageId not have topic " + entry.getKey());
}
int currentResult = entry.getValue().compareTo(otherMessage);
if (result == 0) {
result = currentResult;
} else if (currentResult == 0) {
continue;
} else if (result != currentResult) {
throw new IllegalArgumentException(
"Different MessageId in Map get different compare result");
} else {
continue;
}
}
return result;
}View on GitHub (pinned to 820761864e)
Solutions
- Verify both cursors cover the same topic set (compare key sets) before comparing
- Normalize cursor construction: always build the multi-id from the current topic partition list via the client admin/lookup, never from stored partial maps
- After a partition change, migrate the stored cursor per key: for keys present keep them, for missing keys default to earliest
- Catch IllegalArgumentException and rebuild the cursor for the actual partition set
Example fix
// before
int r = a.compareTo(b); // 'Other MessageId not have topic ...'
// after
if (!a.getMap().keySet().equals(b.getMap().keySet())) {
b = rebuildCursorForTopics(a.getMap().keySet()); // align key sets first
}
int r = a.compareTo(b); Defensive patterns
Strategy: validation
Validate before calling
boolean sameTopics(MultiMessageIdImpl a, MultiMessageIdImpl b) {
return a.getMap().keySet().equals(b.getMap().keySet());
} Type guard
boolean comparableKeySets(MultiMessageIdImpl a, MultiMessageIdImpl b) {
return a.getMap().keySet().equals(b.getMap().keySet());
} Try / catch
try {
int r = a.compareTo(b);
} catch (IllegalArgumentException e) {
// key sets differ: rebuild the cursor over the actual partition set
} Prevention
- Always construct multi-ids from the same authoritative partition list
- Validate key-set equality before comparison
- Migrate stored cursors key-by-key when partition naming changes
When it happens
Trigger: Comparing two multi-partition cursors whose topic/partition key sets are disjoint or partially overlapping with same size — e.g. one built from partitions of topic 'a-partition-' and the other after a partition count change that yields different keys, or cursors for different topics entirely.
Common situations: Re-partitioned topics; cursors from topics with different partition naming; code that builds MultiMessageIdImpl from ad-hoc maps with mismatched keys; comparing cursors across different partitioned topics by mistake.
Related errors
- expected MultiMessageIdImpl object. Got instance of
- Current size and other size not equals
- Different MessageId in Map get different compare result
- isDuplicated cannot accept
- ResourceGroupCreate: Invalid null ResourceGroup config
AI-assisted analysis of apache/pulsar@820761864e (2026-09-06).
Data as JSON: /api/errors/d62eb5eb78266141.
Report an issue: GitHub.