{"record":{"id":"d466886bf9595c04","repo":"apache/pulsar","slug":"invalid-key-shared-mode-keysharedmode","errorCode":null,"errorMessage":"Invalid key-shared mode: ${keySharedMode}","messagePattern":"Invalid key-shared mode: (.+?)","errorType":"validation","errorClass":"java.lang.IllegalArgumentException","httpStatus":null,"severity":"error","filePath":"pulsar-broker/src/main/java/org/apache/pulsar/broker/service/persistent/PersistentStickyKeyDispatcherMultipleConsumers.java","lineNumber":122,"sourceCode":"                topic.getBrokerService().executor(), this::cancelPendingRead, () -> reScheduleReadInMs(0),\n                () -> havePendingRead, this::getReadMoreEntriesCallCount, () -> !redeliveryMessages.isEmpty());\n        this.selector = selector;\n    }\n\n    private static StickyKeyConsumerSelector createSelector(KeySharedMeta ksm, ServiceConfiguration conf) {\n        boolean drainingHashesRequired =\n                ksm.getKeySharedMode() == KeySharedMode.AUTO_SPLIT && !ksm.isAllowOutOfOrderDelivery();\n        switch (ksm.getKeySharedMode()) {\n        case AUTO_SPLIT:\n            if (conf.isSubscriptionKeySharedUseConsistentHashing()) {\n                return new ConsistentHashingStickyKeyConsumerSelector(\n                        conf.getSubscriptionKeySharedConsistentHashingReplicaPoints(), drainingHashesRequired);\n            }\n            return new HashRangeAutoSplitStickyKeyConsumerSelector(drainingHashesRequired);\n        case STICKY:\n            return new HashRangeExclusiveStickyKeyConsumerSelector();\n        default:\n            throw new IllegalArgumentException(\"Invalid key-shared mode: \" + ksm.getKeySharedMode());\n        }\n    }\n\n    private void stickyKeyHashUnblocked(int stickyKeyHash) {\n        if (stickyKeyHash > -1) {\n            log.debug()\n                    .attr(\"stickyKeyHash\", stickyKeyHash)\n                    .log(\"Sticky key hash is unblocked\");\n        } else {\n            log.debug(\"Some sticky key hashes are unblocked\");\n        }\n        reScheduleReadWithKeySharedUnblockingInterval();\n    }\n\n    private void reScheduleReadWithKeySharedUnblockingInterval() {\n        rescheduleReadHandler.rescheduleRead();\n    }\n","sourceCodeStart":104,"sourceCodeEnd":140,"githubUrl":"https://github.com/apache/pulsar/blob/820761864ed8e2a7d2e52dd9763ad2ae117c1395/pulsar-broker/src/main/java/org/apache/pulsar/broker/service/persistent/PersistentStickyKeyDispatcherMultipleConsumers.java#L104-L140","documentation":"The broker's Key_Shared dispatcher only supports the AUTO_SPLIT and STICKY key-shared modes. createSelector switches on KeySharedMeta.getKeySharedMode() and throws IllegalArgumentException for any other value (or an unset/null mode that resolves to nothing handled). The switch exhaustively handles the two defined modes, so hitting the default means the subscription metadata carries a mode the broker doesn't recognize or support.","triggerScenarios":"Subscribing with KeySharedMeta whose keySharedMode field is unset or set to a proto enum value the broker's KeySharedMode doesn't map to (e.g. a value added in a newer client/protocol version than the broker understands, or UNSET); deserialization producing a mode outside {AUTO_SPLIT, STICKY}.","commonSituations":"Newer client SDK sending a newly introduced KeySharedMode enum value to an older broker; hand-constructed subscribe commands where keySharedMode was never set (UNSET); proxy or third-party tooling rewriting KeySharedMeta and corrupting the enum; cross-version upgrades where broker lags client protocol.","solutions":["Set keySharedMode explicitly to AUTO_SPLIT or STICKY in the subscription's KeySharedMeta.","Upgrade the broker to a version whose KeySharedMode enum includes the value the client is sending (check protocol/proto compatibility between client and broker versions).","Inspect the actual subscribe payload (proxy logs / client debug) to confirm which numeric enum value is being sent; fix whichever component leaves it UNSET."],"exampleFix":"// before\nKeySharedMeta ksm = new KeySharedMeta();\n// keySharedMode left UNSET -> Invalid key-shared mode: UNSET\n// after\nKeySharedMeta ksm = new KeySharedMeta()\n    .setKeySharedMode(KeySharedMode.AUTO_SPLIT);","handlingStrategy":"validation","validationCode":"static void requireSupportedKeySharedMode(KeySharedMeta ksm) {\n    var mode = ksm.getKeySharedMode();\n    if (mode != KeySharedMode.AUTO_SPLIT && mode != KeySharedMode.STICKY) {\n        throw new IllegalArgumentException(\n            \"keySharedMode must be AUTO_SPLIT or STICKY, got: \" + mode);\n    }\n}\n// call before building/serializing the subscribe command","typeGuard":"static boolean isSupportedKeySharedMode(KeySharedMeta ksm) {\n    return ksm.getKeySharedMode() == KeySharedMode.AUTO_SPLIT\n        || ksm.getKeySharedMode() == KeySharedMode.STICKY;\n}","tryCatchPattern":"try {\n    subscribe(ksm);\n} catch (IllegalArgumentException e) {\n    if (e.getMessage().startsWith(\"Invalid key-shared mode\")) {\n        log.warn(\"Unsupported KeySharedMode from client; resubscribing with AUTO_SPLIT\");\n        subscribe(ksm.setKeySharedMode(KeySharedMode.AUTO_SPLIT));\n    } else throw e;\n}","preventionTips":["Always set keySharedMode explicitly; never rely on the proto default/UNSET.","Keep client and broker protocol versions aligned; check KeySharedMode enum compatibility before upgrading clients ahead of brokers.","Log the raw KeySharedMode in client debug output to catch UNSET early in tests."],"tags":["pulsar","key-shared","enum","protocol-compatibility"],"backgroundTag":"unsupported-enum-value","analyzedSha":"820761864ed8e2a7d2e52dd9763ad2ae117c1395","analyzedAt":"2026-09-06T00:14:20.138Z","contentChangedAt":"2026-09-06T00:14:20.138Z","schemaVersion":2},"datasetVersion":"2026-09-14T00:17:10.932Z"}