{"id":"b20911716859e58c","repo":"apache/kafka","slug":"coordinator-selected-invalid-assignment-protocol","errorCode":null,"errorMessage":"Coordinator selected invalid assignment protocol: {}","messagePattern":"Coordinator selected invalid assignment protocol: (.+?)","errorType":"exception","errorClass":"IllegalStateException","httpStatus":null,"severity":"error","filePath":"clients/src/main/java/org/apache/kafka/clients/consumer/internals/ConsumerCoordinator.java","lineNumber":391,"sourceCode":"\n        return null;\n    }\n\n    @SuppressWarnings(\"removal\")\n    @Override\n    protected void onJoinComplete(int generation,\n                                  String memberId,\n                                  String assignmentStrategy,\n                                  ByteBuffer assignmentBuffer) {\n        log.debug(\"Executing onJoinComplete with generation {} and memberId {}\", generation, memberId);\n\n        // Only the leader is responsible for monitoring for metadata changes (i.e. partition changes)\n        if (!isLeader)\n            assignmentSnapshot = null;\n\n        ConsumerPartitionAssignor assignor = lookupAssignor(assignmentStrategy);\n        if (assignor == null)\n            throw new IllegalStateException(\"Coordinator selected invalid assignment protocol: \" + assignmentStrategy);\n\n        // Give the assignor a chance to update internal state based on the received assignment\n        groupMetadata = new ConsumerGroupMetadata(rebalanceConfig.groupId, generation, memberId, rebalanceConfig.groupInstanceId);\n\n        SortedSet<TopicPartition> ownedPartitions = new TreeSet<>(COMPARATOR);\n        ownedPartitions.addAll(subscriptions.assignedPartitions());\n\n        // should at least encode the short version\n        if (assignmentBuffer.remaining() < 2)\n            throw new IllegalStateException(\"There are insufficient bytes available to read assignment from the sync-group response (\" +\n                \"actual byte size \" + assignmentBuffer.remaining() + \") , this is not expected; \" +\n                \"it is possible that the leader's assign function is buggy and did not return any assignment for this member, \" +\n                \"or because static member is configured and the protocol is buggy hence did not get the assignment for this member\");\n\n        Assignment assignment = ConsumerProtocol.deserializeAssignment(assignmentBuffer);\n\n        SortedSet<TopicPartition> assignedPartitions = new TreeSet<>(COMPARATOR);\n        assignedPartitions.addAll(assignment.partitions());","sourceCodeStart":373,"sourceCodeEnd":409,"githubUrl":"https://github.com/apache/kafka/blob/c31c9215e131f8c17e79f8901b48c13ee6aa8e7a/clients/src/main/java/org/apache/kafka/clients/consumer/internals/ConsumerCoordinator.java#L373-L409","documentation":"IllegalStateException thrown from ConsumerCoordinator.onJoinComplete (ConsumerCoordinator.java:391) when the broker's SyncGroup response selects an assignment strategy whose name does not match any assignor configured on this client (lookupAssignor returns null). The client trusts the coordinator's choice, so an unknown name means this client and the rest of the group are out of sync. It typically signals a version skew or a missing custom assignor class rather than a broker bug.","triggerScenarios":"At the end of a successful rebalance, the coordinator returns assignmentStrategy='X'; ConsumerCoordinator.lookupAssignor('X') (ConsumerCoordinator.java:331) returns null because none of this client's assignors matches, so onJoinComplete throws.","commonSituations":"Broker-side group leader advertises an assignor this client does not ship (e.g. custom JAR missing from classpath); partial rollout of a new assignor across group members; client downgrade while the group still contains newer members; a custom assignor whose name() was changed between releases.","solutions":["Add the missing assignor class to this client's partition.assignment.strategy and ensure its JAR is on the classpath.","Roll all group members to the same Kafka client version so the assignor set is identical across the group.","For custom assignors, confirm the class's name() exactly matches what the leader advertised.","If the group is in a bad state, bounce the affected members or roll back to the previously working client version."],"exampleFix":null,"handlingStrategy":"try-catch","validationCode":null,"typeGuard":null,"tryCatchPattern":"try {\n    consumer.poll(Duration.ofSeconds(1));   // can surface during onJoinComplete\n} catch (IllegalStateException e) {\n    if (e.getMessage().contains(\"invalid assignment protocol\")) {\n        // broker returned a protocol this client doesn't know: rejoin with aligned config\n        consumer.close();\n        consumer = new KafkaConsumer<>(alignedProps);\n        consumer.subscribe(topics);\n    } else throw e;\n}","preventionTips":["Keep the assignor class list identical across all members of the group.","Align client library versions in every member so the broker-selected protocol is always recognized.","Roll the whole consumer group together when deploying a new assignor — avoid mid-roll version skew.","Treat this as a deployment/compatibility fault, not transient: fix the config before retrying."],"tags":["consumer","assignor","rebalance","version-skew"],"analyzedSha":"c31c9215e131f8c17e79f8901b48c13ee6aa8e7a","analyzedAt":"2026-08-03T12:34:05.770Z","schemaVersion":2}