{"id":"9ba469246c855392","repo":"apache/kafka","slug":"specified-assignors-do-not-have-commonly-suppor","errorCode":null,"errorMessage":"Specified assignors {} do not have commonly supported rebalance protocol","messagePattern":"Specified assignors (.+?) do not have commonly supported rebalance protocol","errorType":"validation","errorClass":"IllegalArgumentException","httpStatus":null,"severity":"error","filePath":"clients/src/main/java/org/apache/kafka/clients/consumer/internals/ConsumerCoordinator.java","lineNumber":264,"sourceCode":"\n        if (autoCommitEnabled)\n            this.nextAutoCommitTimer = time.timer(autoCommitIntervalMs);\n\n        // select the rebalance protocol such that:\n        //   1. only consider protocols that are supported by all the assignors. If there is no common protocols supported\n        //      across all the assignors, throw an exception.\n        //   2. if there are multiple protocols that are commonly supported, select the one with the highest id (i.e. the\n        //      id number indicates how advanced the protocol is).\n        // we know there are at least one assignor in the list, no need to double check for NPE\n        if (!assignors.isEmpty()) {\n            List<RebalanceProtocol> supportedProtocols = new ArrayList<>(assignors.get(0).supportedProtocols());\n\n            for (ConsumerPartitionAssignor assignor : assignors) {\n                supportedProtocols.retainAll(assignor.supportedProtocols());\n            }\n\n            if (supportedProtocols.isEmpty()) {\n                throw new IllegalArgumentException(\"Specified assignors \" +\n                    assignors.stream().map(ConsumerPartitionAssignor::name).collect(Collectors.toSet()) +\n                    \" do not have commonly supported rebalance protocol\");\n            }\n\n            Collections.sort(supportedProtocols);\n\n            protocol = supportedProtocols.get(supportedProtocols.size() - 1);\n        } else {\n            protocol = null;\n        }\n\n        this.rebalanceCallbackMetricsManager = new RebalanceCallbackMetricsManager(metrics, metricGrpPrefix);\n        this.rebalanceListenerInvoker = new ConsumerRebalanceListenerInvoker(\n            logContext,\n            subscriptions,\n            time,\n            rebalanceCallbackMetricsManager\n        );","sourceCodeStart":246,"sourceCodeEnd":282,"githubUrl":"https://github.com/apache/kafka/blob/c31c9215e131f8c17e79f8901b48c13ee6aa8e7a/clients/src/main/java/org/apache/kafka/clients/consumer/internals/ConsumerCoordinator.java#L246-L282","documentation":"IllegalArgumentException thrown in the ConsumerCoordinator constructor (ConsumerCoordinator.java:264) when the configured partition assignors share no common rebalance protocol. Each ConsumerPartitionAssignor declares supportedProtocols() (EAGER or COOPERATIVE); the constructor intersects them. Mixing an eager-only assignor (RangeAssignor, RoundRobinAssignor, StickyAssignor) with a cooperative-only one (CooperativeStickyAssignor) yields an empty intersection and fails fast at consumer creation.","triggerScenarios":"Constructing a KafkaConsumer whose partition.assignment.strategy lists assignors from incompatible protocol families — e.g. RangeAssignor + CooperativeStickyAssignor. The intersection loop at ConsumerCoordinator.java:259-261 reduces supportedProtocols to empty.","commonSituations":"Migrating from eager to cooperative rebalancing and accidentally listing both styles; copy-pasting config snippets that mix strategies; older pre-2.4 examples combined with newer assignors; rolling out a custom assignor that declares a different protocol than the existing ones.","solutions":["Use assignors from a single protocol family — either all eager (RangeAssignor, RoundRobinAssignor, StickyAssignor) or all cooperative (CooperativeStickyAssignor).","When migrating eager to cooperative per KIP-429, do it in two rolling steps: first add the cooperative assignor to the end of the list on every member, then in a second rollout remove the eager entries.","Remove the conflicting assignor from partition.assignment.strategy entirely."],"exampleFix":"// before — mixes eager + cooperative, no common protocol\nprops.put(ConsumerConfig.PARTITION_ASSIGNMENT_STRATEGY_CONFIG,\n    RangeAssignor.class.getName() + \",\" +\n    CooperativeStickyAssignor.class.getName());\nnew KafkaConsumer<String,String>(props);   // throws IllegalArgumentException\n\n// after — pick one family\nprops.put(ConsumerConfig.PARTITION_ASSIGNMENT_STRATEGY_CONFIG,\n    CooperativeStickyAssignor.class.getName());","handlingStrategy":"validation","validationCode":"// Before building the consumer, verify configured assignors share a protocol\nList<ConsumerPartitionAssignor> as = Arrays.asList(\n    new org.apache.kafka.clients.consumer.CooperativeStickyAssignor());\nSet<RebalanceProtocol> common = new HashSet<>(as.get(0).supportedProtocols());\nfor (ConsumerPartitionAssignor a : as) common.retainAll(a.supportedProtocols());\nif (common.isEmpty())\n    throw new IllegalArgumentException(\"assignors share no common rebalance protocol\");","typeGuard":null,"tryCatchPattern":"try {\n    consumer = new KafkaConsumer<>(props);\n} catch (IllegalArgumentException e) {\n    // assignors were incompatible (e.g. mixed eager + cooperative); pick one family\n    props.put(ConsumerConfig.PARTITION_ASSIGNMENT_STRATEGY_CONFIG,\n              CooperativeStickyAssignor.class.getName());\n    consumer = new KafkaConsumer<>(props);\n}","preventionTips":["Do not mix eager (RangeAssignor, StickyAssignor) and cooperative (CooperativeStickyAssignor) assignors in one config.","Standardize a single assignor across every member of the consumer group.","Treat a custom assignor's supportedProtocols() as part of its public contract and test intersection."],"tags":["configuration","consumer","assignor","rebalance"],"analyzedSha":"c31c9215e131f8c17e79f8901b48c13ee6aa8e7a","analyzedAt":"2026-08-03T12:34:05.770Z","schemaVersion":2}