apache/kafka · error · IllegalArgumentException

Unknown rebalance protocol id: {id}

Error message

Unknown rebalance protocol id: {id}

What it means

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.

Source

Thrown at clients/src/main/java/org/apache/kafka/clients/consumer/ConsumerPartitionAssignor.java:409

        public byte id() {
            return id;
        }

        /**
         * Returns the rebalance protocol for the given identifier.
         *
         * @param id The identifier for the rebalance protocol
         * @return The corresponding rebalance protocol
         * @throws IllegalArgumentException If the ID is not recognized
         */
        public static RebalanceProtocol forId(byte id) {
            switch (id) {
                case 0:
                    return EAGER;
                case 1:
                    return COOPERATIVE;
                default:
                    throw new IllegalArgumentException("Unknown rebalance protocol id: " + id);
            }
        }
    }

    /**
     * Get a list of configured instances of {@link org.apache.kafka.clients.consumer.ConsumerPartitionAssignor}
     * based on the class names/types specified by {@link org.apache.kafka.clients.consumer.ConsumerConfig#PARTITION_ASSIGNMENT_STRATEGY_CONFIG}
     */
    static List<ConsumerPartitionAssignor> getAssignorInstances(List<String> assignorClasses, Map<String, Object> configs) {
        List<ConsumerPartitionAssignor> assignors = new ArrayList<>();
        // a map to store assignor name -> assignor class name
        Map<String, String> assignorNameMap = new HashMap<>();

        for (Object klass : assignorClasses) {
            // first try to get the class if passed in as a string
            if (klass instanceof String) {
                try {
                    klass = Utils.loadClass((String) klass, Object.class);

View on GitHub (pinned to c31c9215e1)

Solutions

  1. Upgrade kafka-clients to a version that understands the rebalance protocol id the broker is sending.
  2. Ensure no proxy/interceptor is rewriting group protocol fields.
  3. If you see this from a custom assignor under test, only emit RebalanceProtocol.EAGER.id (0) or COOPERATIVE.id (1).

Example fix

// before: client older than broker introducing protocol id 2+
// forId(2) -> throws

// after: align versions
<dependency>
  <groupId>org.apache.kafka</groupId>
  <artifactId>kafka-clients</artifactId>
  <version>3.9.0</version> <!-- match broker -->
</dependency>
Defensive patterns

Strategy: try-catch

Type guard

// Narrow a raw byte to RebalanceProtocol safely:
static Optional<ConsumerPartitionAssignor.RebalanceProtocol> safeRebalanceProtocol(byte id) {
    return Arrays.stream(ConsumerPartitionAssignor.RebalanceProtocol.values()).filter(p -> p.id() == id).findFirst();
}

Try / catch

// RebalanceProtocol.forId is invoked from wire decoding; application code consumes the enum.
try {
    ConsumerPartitionAssignor.RebalanceProtocol p = ConsumerPartitionAssignor.RebalanceProtocol.forId(rawByte);
} catch (IllegalArgumentException e) {
    log.warn("Unknown rebalance protocol id {} from broker; treating as EAGER", rawByte);
}

Prevention

When it happens

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

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

Related errors


AI-assisted analysis of apache/kafka@c31c9215e1 (2026-08-03). Data as JSON: /data/errors/5fa0f79121496a39.json. Report an issue: GitHub.