apache/pulsar · error · java.lang.IllegalArgumentException

Invalid key-shared mode: ${keySharedMode}

Error message

Invalid key-shared mode: ${keySharedMode}

What it means

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.

Source

Thrown at pulsar-broker/src/main/java/org/apache/pulsar/broker/service/persistent/PersistentStickyKeyDispatcherMultipleConsumers.java:122

                topic.getBrokerService().executor(), this::cancelPendingRead, () -> reScheduleReadInMs(0),
                () -> havePendingRead, this::getReadMoreEntriesCallCount, () -> !redeliveryMessages.isEmpty());
        this.selector = selector;
    }

    private static StickyKeyConsumerSelector createSelector(KeySharedMeta ksm, ServiceConfiguration conf) {
        boolean drainingHashesRequired =
                ksm.getKeySharedMode() == KeySharedMode.AUTO_SPLIT && !ksm.isAllowOutOfOrderDelivery();
        switch (ksm.getKeySharedMode()) {
        case AUTO_SPLIT:
            if (conf.isSubscriptionKeySharedUseConsistentHashing()) {
                return new ConsistentHashingStickyKeyConsumerSelector(
                        conf.getSubscriptionKeySharedConsistentHashingReplicaPoints(), drainingHashesRequired);
            }
            return new HashRangeAutoSplitStickyKeyConsumerSelector(drainingHashesRequired);
        case STICKY:
            return new HashRangeExclusiveStickyKeyConsumerSelector();
        default:
            throw new IllegalArgumentException("Invalid key-shared mode: " + ksm.getKeySharedMode());
        }
    }

    private void stickyKeyHashUnblocked(int stickyKeyHash) {
        if (stickyKeyHash > -1) {
            log.debug()
                    .attr("stickyKeyHash", stickyKeyHash)
                    .log("Sticky key hash is unblocked");
        } else {
            log.debug("Some sticky key hashes are unblocked");
        }
        reScheduleReadWithKeySharedUnblockingInterval();
    }

    private void reScheduleReadWithKeySharedUnblockingInterval() {
        rescheduleReadHandler.rescheduleRead();
    }

View on GitHub (pinned to 820761864e)

Solutions

  1. Set keySharedMode explicitly to AUTO_SPLIT or STICKY in the subscription's KeySharedMeta.
  2. 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).
  3. Inspect the actual subscribe payload (proxy logs / client debug) to confirm which numeric enum value is being sent; fix whichever component leaves it UNSET.

Example fix

// before
KeySharedMeta ksm = new KeySharedMeta();
// keySharedMode left UNSET -> Invalid key-shared mode: UNSET
// after
KeySharedMeta ksm = new KeySharedMeta()
    .setKeySharedMode(KeySharedMode.AUTO_SPLIT);
Defensive patterns

Strategy: validation

Validate before calling

static void requireSupportedKeySharedMode(KeySharedMeta ksm) {
    var mode = ksm.getKeySharedMode();
    if (mode != KeySharedMode.AUTO_SPLIT && mode != KeySharedMode.STICKY) {
        throw new IllegalArgumentException(
            "keySharedMode must be AUTO_SPLIT or STICKY, got: " + mode);
    }
}
// call before building/serializing the subscribe command

Type guard

static boolean isSupportedKeySharedMode(KeySharedMeta ksm) {
    return ksm.getKeySharedMode() == KeySharedMode.AUTO_SPLIT
        || ksm.getKeySharedMode() == KeySharedMode.STICKY;
}

Try / catch

try {
    subscribe(ksm);
} catch (IllegalArgumentException e) {
    if (e.getMessage().startsWith("Invalid key-shared mode")) {
        log.warn("Unsupported KeySharedMode from client; resubscribing with AUTO_SPLIT");
        subscribe(ksm.setKeySharedMode(KeySharedMode.AUTO_SPLIT));
    } else throw e;
}

Prevention

When it happens

Trigger: 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}.

Common situations: 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.

Related errors


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