apache/pulsar · error · java.lang.IllegalStateException
MessageIdV5 missing multi-topic vector — was the message del
Error message
MessageIdV5 missing multi-topic vector — was the message delivered through a multi-topic stream consumer?
What it means
Thrown by MultiTopicStreamConsumer.fanOutCumulativeAck when the MessageIdV5 lacks its multiTopicVector(). Without the per-topic id map, the consumer cannot route the cumulative ack across the topic set, so it fails with IllegalStateException.
Source
Thrown at pulsar-client-v5/src/main/java/org/apache/pulsar/client/impl/v5/MultiTopicStreamConsumer.java:334
public void acknowledgeCumulative(MessageId messageId, Transaction txn) {
// Transactions on multi-topic are best-effort across per-topic consumers — each
// per-topic ack is independently transactional. See note in the design doc.
fanOutCumulativeAck(messageId, (sc, vector) -> sc.ackUpToVector(vector));
}
/**
* For a cumulative ack on a multi-topic message, look up its multi-topic vector
* and invoke the per-topic ack on every parent topic.
*/
private void fanOutCumulativeAck(MessageId messageId,
java.util.function.BiConsumer<ScalableStreamConsumer<T>,
Map<Long, org.apache.pulsar.client.api.MessageId>> action) {
if (!(messageId instanceof MessageIdV5 id)) {
throw new IllegalArgumentException("Expected MessageIdV5, got: " + messageId.getClass());
}
Map<String, Map<Long, org.apache.pulsar.client.api.MessageId>> vector = id.multiTopicVector();
if (vector == null) {
throw new IllegalStateException("MessageIdV5 missing multi-topic vector — was the"
+ " message delivered through a multi-topic stream consumer?");
}
for (var entry : vector.entrySet()) {
PerTopic<T> state = perTopic.get(entry.getKey());
if (state == null) {
// Topic left the matching set since this message was enqueued: we've
// detached it and no longer ack removed topics, so skip its slice.
continue;
}
action.accept(state.consumer, entry.getValue());
}
}
@Override
public AsyncStreamConsumer<T> async() {
return asyncView;
}
View on GitHub (pinned to 820761864e)
Solutions
- Ack with ids delivered by this exact consumer instance
- Verify id.multiTopicVector() != null before calling acknowledgeCumulative
- When persisting ids, serialize the full multi-topic metadata
Example fix
// before
streamConsumer.acknowledgeCumulative(id); // vector-less id
// after
if (id instanceof MessageIdV5 v5 && v5.multiTopicVector() != null) {
streamConsumer.acknowledgeCumulative(v5);
} Defensive patterns
Strategy: type-guard
Validate before calling
if (id instanceof MessageIdV5 v5 && v5.multiTopicVector() == null) { handleVectorless(); } Type guard
static boolean hasMultiTopicVector(MessageId id) { return id instanceof MessageIdV5 v5 && v5.multiTopicVector() != null; } Try / catch
try { consumer.acknowledgeCumulative(id); } catch (IllegalStateException e) { log.warn("missing multi-topic vector", e); } Prevention
- Serialize full multi-topic metadata when persisting ids
- Ack only with ids from multi-topic stream delivery
When it happens
Trigger: Calling acknowledgeCumulative with a MessageIdV5 not produced by multi-topic stream delivery — single-topic v5 id, deserialized id missing vector metadata, or hand-constructed id.
Common situations: Persisting and later replaying ids without the multi-topic vector; acking across consumer instances; client version migration dropping metadata.
Related errors
- MessageIdV5 missing parent topic — was the message delivered
- Expected MessageIdV5, got: ${messageId.getClass()}
- Expected MessageIdV5, got: ${messageId.getClass()}
- Try to reserve/release memory failed, the param memorySize i
- Failed to decode message from topic ${topic} with schemaId $
AI-assisted analysis of apache/pulsar@820761864e (2026-09-06).
Data as JSON: /api/errors/06adaddb23f5c1cb.
Report an issue: GitHub.