{"record":{"id":"7a2336e0e2e945f8","repo":"apache/pulsar","slug":"expected-messageidv5-got-messageid-getclass","errorCode":null,"errorMessage":"Expected MessageIdV5, got: ${messageId.getClass()}","messagePattern":"Expected MessageIdV5, got: (.+?)","errorType":"exception","errorClass":"java.lang.IllegalArgumentException","httpStatus":null,"severity":"error","filePath":"pulsar-client-v5/src/main/java/org/apache/pulsar/client/impl/v5/MultiTopicQueueConsumer.java","lineNumber":331,"sourceCode":"    @Override\n    public void acknowledge(MessageId messageId) {\n        routeAck(messageId, ptc -> ptc.acknowledge(messageId));\n    }\n\n    @Override\n    public void acknowledge(MessageId messageId, Transaction txn) {\n        routeAck(messageId, ptc -> ptc.acknowledge(messageId, txn));\n    }\n\n    @Override\n    public void negativeAcknowledge(MessageId messageId) {\n        routeAck(messageId, ptc -> ptc.negativeAcknowledge(messageId));\n    }\n\n    /** Look up the per-topic consumer via the parent topic tag and delegate. */\n    private void routeAck(MessageId messageId, java.util.function.Consumer<QueueConsumer<T>> action) {\n        if (!(messageId instanceof MessageIdV5 id)) {\n            throw new IllegalArgumentException(\"Expected MessageIdV5, got: \" + messageId.getClass());\n        }\n        String parent = id.parentTopic();\n        if (parent == null) {\n            throw new IllegalStateException(\"MessageIdV5 missing parent topic — was the message\"\n                    + \" delivered through a multi-topic consumer?\");\n        }\n        PerTopicState<T> state = perTopic.get(parent);\n        if (state == null) {\n            // Topic was removed between deliver and ack. Fine — broker has dropped the\n            // session for that topic. Drop the ack silently.\n            log.debug().attr(\"topic\", parent)\n                    .log(\"Ack for removed topic; dropping\");\n            return;\n        }\n        action.accept(state.consumer);\n    }\n\n    @Override","sourceCodeStart":313,"sourceCodeEnd":349,"githubUrl":"https://github.com/apache/pulsar/blob/820761864ed8e2a7d2e52dd9763ad2ae117c1395/pulsar-client-v5/src/main/java/org/apache/pulsar/client/impl/v5/MultiTopicQueueConsumer.java#L313-L349","documentation":"Thrown by MultiTopicQueueConsumer.routeAck when the acked MessageId is not a MessageIdV5 instance. Multi-topic routing requires the id to carry per-topic metadata that only MessageIdV5 exposes; any other MessageId implementation cannot be routed to the correct underlying topic consumer.","triggerScenarios":"Calling acknowledge(messageId) or negativeAcknowledge(messageId) on a MultiTopicQueueConsumer with a MessageId obtained from a different consumer type (single-topic consumer, MessageIdV3, or a deserialized id).","commonSituations":"Mixing message ids between a regular topic consumer and a multi-topic consumer; replaying ids persisted from an older client version; constructing an id manually.","solutions":["Ack only with MessageId instances returned by the same multi-topic consumer's receive()","Check messageId instanceof MessageIdV5 before passing it to acknowledge/negativeAcknowledge","If migrating from another client version, re-receive the message rather than reusing old ids"],"exampleFix":"// before\nconsumer.acknowledge(oldMessageId); // MessageIdV3 from another consumer\n// after\nif (oldMessageId instanceof MessageIdV5 id) {\n    consumer.acknowledge(id);\n}","handlingStrategy":"type-guard","validationCode":null,"typeGuard":"static boolean isAckable(MessageId id) { return id instanceof MessageIdV5; }","tryCatchPattern":"try { consumer.acknowledge(id); } catch (IllegalArgumentException e) { log.error(\"wrong id type for multi-topic ack\", e); }","preventionTips":["Only ack ids from the same consumer instance","Avoid mixing MessageId implementations across consumers"],"tags":["pulsar","client","ack","type-mismatch"],"backgroundTag":"message-id-type-mismatch","analyzedSha":"820761864ed8e2a7d2e52dd9763ad2ae117c1395","analyzedAt":"2026-09-06T00:14:20.138Z","contentChangedAt":"2026-09-06T00:14:20.138Z","schemaVersion":2},"datasetVersion":"2026-09-14T05:17:10.506Z"}