{"id":"5fa0f79121496a39","repo":"apache/kafka","slug":"unknown-rebalance-protocol-id-id","errorCode":null,"errorMessage":"Unknown rebalance protocol id: {id}","messagePattern":"Unknown rebalance protocol id: (.+?)","errorType":"exception","errorClass":"IllegalArgumentException","httpStatus":null,"severity":"error","filePath":"clients/src/main/java/org/apache/kafka/clients/consumer/ConsumerPartitionAssignor.java","lineNumber":409,"sourceCode":"        public byte id() {\n            return id;\n        }\n\n        /**\n         * Returns the rebalance protocol for the given identifier.\n         *\n         * @param id The identifier for the rebalance protocol\n         * @return The corresponding rebalance protocol\n         * @throws IllegalArgumentException If the ID is not recognized\n         */\n        public static RebalanceProtocol forId(byte id) {\n            switch (id) {\n                case 0:\n                    return EAGER;\n                case 1:\n                    return COOPERATIVE;\n                default:\n                    throw new IllegalArgumentException(\"Unknown rebalance protocol id: \" + id);\n            }\n        }\n    }\n\n    /**\n     * Get a list of configured instances of {@link org.apache.kafka.clients.consumer.ConsumerPartitionAssignor}\n     * based on the class names/types specified by {@link org.apache.kafka.clients.consumer.ConsumerConfig#PARTITION_ASSIGNMENT_STRATEGY_CONFIG}\n     */\n    static List<ConsumerPartitionAssignor> getAssignorInstances(List<String> assignorClasses, Map<String, Object> configs) {\n        List<ConsumerPartitionAssignor> assignors = new ArrayList<>();\n        // a map to store assignor name -> assignor class name\n        Map<String, String> assignorNameMap = new HashMap<>();\n\n        for (Object klass : assignorClasses) {\n            // first try to get the class if passed in as a string\n            if (klass instanceof String) {\n                try {\n                    klass = Utils.loadClass((String) klass, Object.class);","sourceCodeStart":391,"sourceCodeEnd":427,"githubUrl":"https://github.com/apache/kafka/blob/c31c9215e131f8c17e79f8901b48c13ee6aa8e7a/clients/src/main/java/org/apache/kafka/clients/consumer/ConsumerPartitionAssignor.java#L391-L427","documentation":"Thrown by ConsumerPartitionAssignor.RebalanceProtocol.forId(byte) when deserializing a rebalance-protocol byte that is neither 0 (EAGER) nor 1 (COOPERATIVE). RebalanceProtocol is part of the consumer-group assignor handshake; an unknown id means the wire value cannot be mapped to a known protocol.","triggerScenarios":"Deserialization of a group-assignment or sync-group response (or unit tests of assignors) where the rebalance protocol id is outside {0,1}. Reached inside ConsumerPartitionAssignor internals when interpreting protocol fields sent by the broker or by another assignor instance.","commonSituations":"Client/broker version skew where a future broker introduces a new rebalance protocol the current client does not recognize; a non-compliant broker or proxy corrupting the protocol byte; tests using a hand-crafted protocol id without updating the enum.","solutions":["Upgrade kafka-clients to a version that understands the rebalance protocol id the broker is sending.","Ensure no proxy/interceptor is rewriting group protocol fields.","If you see this from a custom assignor under test, only emit RebalanceProtocol.EAGER.id (0) or COOPERATIVE.id (1)."],"exampleFix":"// before: client older than broker introducing protocol id 2+\n// forId(2) -> throws\n\n// after: align versions\n<dependency>\n  <groupId>org.apache.kafka</groupId>\n  <artifactId>kafka-clients</artifactId>\n  <version>3.9.0</version> <!-- match broker -->\n</dependency>","handlingStrategy":"try-catch","validationCode":null,"typeGuard":"// Narrow a raw byte to RebalanceProtocol safely:\nstatic Optional<ConsumerPartitionAssignor.RebalanceProtocol> safeRebalanceProtocol(byte id) {\n    return Arrays.stream(ConsumerPartitionAssignor.RebalanceProtocol.values()).filter(p -> p.id() == id).findFirst();\n}","tryCatchPattern":"// RebalanceProtocol.forId is invoked from wire decoding; application code consumes the enum.\ntry {\n    ConsumerPartitionAssignor.RebalanceProtocol p = ConsumerPartitionAssignor.RebalanceProtocol.forId(rawByte);\n} catch (IllegalArgumentException e) {\n    log.warn(\"Unknown rebalance protocol id {} from broker; treating as EAGER\", rawByte);\n}","preventionTips":["Application code should compare against RebalanceProtocol.COOPERATIVE / EAGER constants directly, never decode a byte.","This signals client/broker version skew - upgrade the client to learn the new protocol id.","Pin your assignor's rebalance protocol via name (e.g. CooperativeStickyAssignor) rather than wire id."],"tags":["consumer","partition-assignor","wire-protocol","version-mismatch","deserialization","java"],"analyzedSha":"c31c9215e131f8c17e79f8901b48c13ee6aa8e7a","analyzedAt":"2026-08-03T12:34:05.770Z","schemaVersion":2}