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

  1. Verify both cursors cover the same topic set (compare key sets) before comparing
  2. Normalize cursor construction: always build the multi-id from the current topic partition list via the client admin/lookup, never from stored partial maps
  3. After a partition change, migrate the stored cursor per key: for keys present keep them, for missing keys default to earliest
  4. 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

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


AI-assisted analysis of apache/pulsar@820761864e (2026-09-06). Data as JSON: /api/errors/d62eb5eb78266141. Report an issue: GitHub.