{"record":{"id":"ad5d3f249159bb20","repo":"apache/pulsar","slug":"not-supported-operation-on-partitioned-topic","errorCode":null,"errorMessage":"Not supported operation on partitioned-topic","messagePattern":"Not supported operation on partitioned-topic","errorType":"exception","errorClass":"IllegalArgumentException","httpStatus":null,"severity":"error","filePath":"pulsar-client/src/main/java/org/apache/pulsar/client/impl/ResetCursorData.java","lineNumber":78,"sourceCode":"            this.entryId = Long.MAX_VALUE;\n        } else if (\"earliest\".equals(position)) {\n            this.ledgerId = -1;\n            this.entryId = -1;\n        } else {\n            throw new IllegalArgumentException(\n                    String.format(\"Invalid value %s for the position. Allowed values are [latest, earliest]\",\n                            position));\n        }\n    }\n\n    public ResetCursorData(MessageId messageId) {\n        MessageIdAdv messageIdAdv = (MessageIdAdv) messageId;\n        this.ledgerId = messageIdAdv.getLedgerId();\n        this.entryId = messageIdAdv.getEntryId();\n        this.batchIndex = messageIdAdv.getBatchIndex();\n        this.partitionIndex = messageIdAdv.getPartitionIndex();\n        if (messageId instanceof TopicMessageId) {\n            throw new IllegalArgumentException(\"Not supported operation on partitioned-topic\");\n        }\n    }\n\n}\n","sourceCodeStart":60,"sourceCodeEnd":83,"githubUrl":"https://github.com/apache/pulsar/blob/820761864ed8e2a7d2e52dd9763ad2ae117c1395/pulsar-client/src/main/java/org/apache/pulsar/client/impl/ResetCursorData.java#L60-L83","documentation":"ResetCursorData's constructor extracts ledgerId, entryId, batchIndex, and partitionIndex from a MessageId by casting it to MessageIdAdv. If the caller passes a TopicMessageId — the aggregated message id type used when consuming a partitioned topic — the code rejects it because a TopicMessageId does not carry a single partition's raw position suitable for cursor reset.","triggerScenarios":"Calling the ResetCursorData constructor (directly or via an admin/client API that builds one) with a MessageId obtained from a consumer subscribed to a partitioned topic, i.e. an instance of TopicMessageId, instead of the underlying partition-level message id.","commonSituations":"Consuming a partitioned topic and passing message.getMessageId() straight into a reset-cursor / seek style call without unwrapping it to the partition's MessageIdAdv; code written against a non-partitioned topic then reused against a partitioned topic.","solutions":["Unwrap the TopicMessageId to its underlying partition message id (e.g. topicMessageId.getInnerMessageId() or cast the TopicMessageId and get the partition-specific MessageId) before constructing ResetCursorData.","Obtain the message id directly from a consumer attached to the specific partition (partition-i topic) rather than from the aggregated partitioned-topic consumer.","If the topic is partitioned and you intend to reset the whole topic, use the partition-aware admin API instead of ResetCursorData with a single message id."],"exampleFix":"// before\nMessageId id = message.getMessageId(); // TopicMessageId on partitioned topic\nResetCursorData data = new ResetCursorData(id);\n\n// after\nMessageId id = message.getMessageId();\nif (id instanceof TopicMessageId) {\n    id = ((TopicMessageId) id).getInnerMessageId();\n}\nResetCursorData data = new ResetCursorData(id);","handlingStrategy":"type-guard","validationCode":"if (messageId instanceof TopicMessageId) {\n    throw new IllegalArgumentException(\"Pass the partition-level message id, not a TopicMessageId\");\n}","typeGuard":"static MessageId requirePartitionMessageId(MessageId id) {\n    return id instanceof TopicMessageId ? ((TopicMessageId) id).getInnerMessageId() : id;\n}","tryCatchPattern":null,"preventionTips":["Always unwrap TopicMessageId before low-level MessageIdAdv operations.","Add an instanceof TopicMessageId check at every boundary where message ids leave consumer code.","Prefer getting ids from a partition-specific consumer when doing cursor/seek operations."],"tags":["pulsar-client","message-id","partitioned-topic","illegal-argument"],"backgroundTag":"unsupported-message-id-type","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"}