{"id":"3d6b106ae4e8504a","repo":"apache/kafka","slug":"subscription-to-topics-partitions-and-pattern-are","errorCode":null,"errorMessage":"Subscription to topics, partitions and pattern are mutually exclusive","messagePattern":"Subscription to topics, partitions and pattern are mutually exclusive","errorType":"exception","errorClass":"IllegalStateException","httpStatus":null,"severity":"error","filePath":"clients/src/main/java/org/apache/kafka/clients/consumer/internals/SubscriptionState.java","lineNumber":189,"sourceCode":"     * be used to check when an assignment has changed.\n     *\n     * @return The current assignment Id\n     */\n    synchronized int assignmentId() {\n        return assignmentId;\n    }\n\n    /**\n     * This method sets the subscription type if it is not already set (i.e. when it is NONE),\n     * or verifies that the subscription type is equal to the give type when it is set (i.e.\n     * when it is not NONE)\n     * @param type The given subscription type\n     */\n    private void setSubscriptionType(SubscriptionType type) {\n        if (this.subscriptionType == SubscriptionType.NONE)\n            this.subscriptionType = type;\n        else if (this.subscriptionType != type)\n            throw new IllegalStateException(SUBSCRIPTION_EXCEPTION_MESSAGE);\n    }\n\n    public synchronized boolean subscribe(Set<String> topics, Optional<ConsumerRebalanceListener> listener) {\n        registerRebalanceListener(listener);\n        setSubscriptionType(SubscriptionType.AUTO_TOPICS);\n        return changeSubscription(topics);\n    }\n\n    public synchronized void subscribe(Pattern pattern, Optional<ConsumerRebalanceListener> listener) {\n        registerRebalanceListener(listener);\n        setSubscriptionType(SubscriptionType.AUTO_PATTERN);\n        this.subscribedPattern = pattern;\n    }\n\n    public synchronized void subscribe(SubscriptionPattern pattern, Optional<ConsumerRebalanceListener> listener) {\n        registerRebalanceListener(listener);\n        setSubscriptionType(SubscriptionType.AUTO_PATTERN_RE2J);\n        this.subscribedRe2JPattern = pattern;","sourceCodeStart":171,"sourceCodeEnd":207,"githubUrl":"https://github.com/apache/kafka/blob/c31c9215e131f8c17e79f8901b48c13ee6aa8e7a/clients/src/main/java/org/apache/kafka/clients/consumer/internals/SubscriptionState.java#L171-L207","documentation":"Thrown by SubscriptionState.setSubscriptionType when the consumer's subscription type has already been set to a different mode (AUTO_TOPICS, AUTO_PATTERN, AUTO_PATTERN_RE2J, or manual assignment). Kafka enforces that a consumer uses exactly one subscription mechanism; mixing subscribe(topics), subscribe(pattern), and assign(partitions) on the same instance is illegal and the state machine rejects it with this message.","triggerScenarios":"Calling consumer.subscribe(Collection<String>) after consumer.subscribe(Pattern), or consumer.assign(...) after subscribe(...), or any combination of the three on the same KafkaConsumer/KafkaShareConsumer instance. Each call routes through setSubscriptionType, which throws if the prior type differs.","commonSituations":"Refactoring a consumer from topic list to pattern (or vice versa) without recreating the consumer; library/framework code that calls subscribe then user code calls assign; mixing manual assignment with group subscription in test harnesses; migrating between share and regular consumers and reusing the instance.","solutions":["Pick one subscription mode (topics, pattern, or manual assign) and use only that for the lifetime of the consumer instance.","If the subscription mode must change, close() the consumer and create a new instance.","Audit framework/wrapper code that may call subscribe internally before your application calls assign (or vice versa).","For pattern subscriptions, ensure you are not also passing a topic list elsewhere in setup."],"exampleFix":"// before\nconsumer.subscribe(Arrays.asList(\"orders\"));\nconsumer.assign(Collections.singletonList(new TopicPartition(\"orders\", 0)));  // throws\n\n// after\n// option A: topic subscription only\nconsumer.subscribe(Arrays.asList(\"orders\"));\n// option B: manual assignment only (new instance)\nconsumer.close();\nconsumer = new KafkaConsumer<>(props);\nconsumer.assign(Collections.singletonList(new TopicPartition(\"orders\", 0)));","handlingStrategy":"validation","validationCode":"// Enforce one subscription mode per consumer instance at construction time.\npublic enum SubscriptionMode { TOPICS, PATTERN, ASSIGNED }\nprivate final SubscriptionMode mode;\n\npublic ShareConsumerRunner(SubProperties props, SubscriptionMode mode) {\n    this.mode = Objects.requireNonNull(mode);\n}\n\nvoid start() {\n    switch (mode) {\n        case TOPICS    -> consumer.subscribe(props.topics);\n        case PATTERN   -> consumer.subscribe(props.pattern);\n        case ASSIGNED  -> consumer.assign(props.partitions);\n    }\n    // No code path may call a second subscription method on this instance.\n}","typeGuard":null,"tryCatchPattern":"try {\n    consumer.subscribe(topics);\n} catch (IllegalStateException e) {\n    if (e.getMessage().contains(\"mutually exclusive\")) {\n        // The consumer was already subscribed/assigned via a different API.\n        // Close it and create a fresh consumer with a single subscription mode.\n        log.error(\"Conflicting subscription on same consumer; recreating\", e);\n        consumer.close();\n        consumer = new KafkaConsumer<>(props);\n        consumer.subscribe(topics);\n    } else {\n        throw e;\n    }\n}","preventionTips":["Choose one of subscribe(topics), subscribe(pattern), or assign(partitions) per consumer instance and never mix.","Wrap the consumer in an application-level class that exposes exactly one subscription method.","Never reuse a closed consumer for a different subscription mode; construct a new one.","Document the chosen subscription mode in the consumer's configuration."],"tags":["consumer","subscription","api-misuse","kafka-client"],"analyzedSha":"c31c9215e131f8c17e79f8901b48c13ee6aa8e7a","analyzedAt":"2026-08-03T12:34:05.770Z","schemaVersion":2}