This document specifies the Kafka protocol APIs used for consumer group management, coordination, and offset tracking. These APIs implement the consumer group protocol that enables dynamic partition assignment and coordinated consumption.
API Key Name Purpose 8 OffsetCommit Commit consumer offsets 9 OffsetFetch Retrieve committed offsets 10 FindCoordinator Locate group coordinator 11 JoinGroup Join or create consumer group 12 Heartbeat Maintain group membership 13 LeaveGroup Leave consumer group 14 SyncGroup Synchronize partition assignments 15 DescribeGroups Describe group state 16 ListGroups List all groups 42 DeleteGroups Delete consumer groups 47 OffsetDelete Delete committed offsets
Consumer group membership protocol from coordinator discovery to leave Consumer Coordinator Consumer Consumer Coordinator Coordinator Find Coordinator FindCoordinatorRequest(group_id) FindCoordinatorResponse(coordinator) Join Group JoinGroupRequest(group_id, protocols) All members send JoinGroup JoinGroupResponse(generation_id, leader, members) Sync Group SyncGroupRequest(assignments) Only leader sends assignments SyncGroupResponse(assignment) Steady State loop [while member of group] HeartbeatRequest HeartbeatResponse Leave Group LeaveGroupRequest LeaveGroupResponse
The FindCoordinator API locates the broker serving as coordinator for a consumer group, transaction, or share group.
Version Kafka Key Changes 0 0.8.2 Initial version (group only) 1 0.10.0 Throttle time 2 0.11.0 Key type (transaction support) 3 2.4.0 Flexible versions 4 3.6.0 Batched requests (KIP-699) 5 3.8.0 TRANSACTION_ABORTABLE errors (KIP-890) 6 4.0.0 Share groups (KIP-932)
FindCoordinatorRequest =>
coordinator_keys: [STRING]
Field Type Description keySTRING Coordinator key (v0-3) key_typeINT8 0=GROUP, 1=TRANSACTION, 2=SHARE coordinator_keysARRAY Multiple keys (v4+)
For key_type=SHARE, the coordinator key format is groupId:topicId:partition.
FindCoordinatorResponse =>
error_message: NULLABLE_STRING
coordinators: [Coordinator]
error_message: NULLABLE_STRING
Field Type Description node_idINT32 Coordinator broker ID (v0-3) hostSTRING Coordinator hostname (v0-3) portINT32 Coordinator port (v0-3)
The coordinator is deterministically selected based on the coordinator key and internal topic:
partition = abs(hash(key)) % internal_topic.partitions
coordinator = leader(internal_topic, partition)
Key types map to internal topics:
GROUP -> __consumer_offsets
TRANSACTION -> __transaction_state
SHARE -> __share_group_state
Aspect Guarantee Determinism Same group ID always maps to same partition Consistency Coordinator stable unless broker fails Failover On coordinator failure, new leader elected
Error Code Retriable Cause Recovery COORDINATOR_NOT_AVAILABLE ✅ Coordinator initializing Wait, retry NOT_COORDINATOR ✅ Coordinator moved Retry FindCoordinator GROUP_AUTHORIZATION_FAILED ❌ No Describe permission Check ACLs
The JoinGroup API joins a consumer to a group, triggering rebalancing if necessary. The coordinator selects a group leader.
Version Kafka Key Changes 0 0.9.0 Initial version 1 0.10.1 Rebalance timeout 4 2.1.0 Second join with assigned member ID 5 2.3.0 Group instance ID 6 2.4.0 Flexible versions 7 2.7.0 Protocol type in response (KIP-559) 8 3.0.0 Reason field (KIP-800) 9 3.5.0 Skip assignment in response
session_timeout_ms: INT32
rebalance_timeout_ms: INT32
group_instance_id: NULLABLE_STRING
Field Type Description group_idSTRING Consumer group identifier session_timeout_msINT32 Session timeout for heartbeats rebalance_timeout_msINT32 Maximum time to join member_idSTRING Member ID (empty for new members) group_instance_idNULLABLE_STRING Static membership ID protocol_typeSTRING Protocol type (e.g., “consumer”) protocolsARRAY Supported assignment protocols
protocol_type: NULLABLE_STRING
protocol_name: NULLABLE_STRING
group_instance_id: NULLABLE_STRING
Field Type Description generation_idINT32 Group generation (increments per rebalance) protocol_nameNULLABLE_STRING Selected assignment protocol leaderSTRING Group leader member ID member_idSTRING Assigned member ID membersARRAY Member list (leader only)
Rebalance with a leader and a follower consumer joining and syncing Consumer A Consumer B Coordinator Consumer A Consumer A Consumer B Consumer B Coordinator Coordinator Initial Join JoinGroup(member_id="") Wait for rebalance_timeout JoinGroup(member_id="") JoinResponse(leader=A, members=[A,B]) JoinResponse(leader=A, members=[]) A is leader, receives member list B is follower, empty members Sync SyncGroup(assignments) SyncGroup(empty) SyncResponse(assignment for A) SyncResponse(assignment for B)
Consumer group coordinator state machine Consumer group coordinator state machine Empty PreparingRebalance CompletingRebalance Stable Dead PreparingRebalance group created first member joins all members joined (or timeout) all members synced member join/leave/heartbeat fail all members leave group deleted
Aspect Guarantee Leader election Coordinator selects leader (often the first to join) Generation ID Increments on each successful rebalance Member ID Assigned by coordinator, must be used in subsequent requests Timeout Members not completing join within rebalance_timeout are removed
With group.instance.id:
Behavior Static Membership Rejoin after restart Preserves member ID Session timeout Longer grace period Rebalance avoidance No rebalance on transient failures
The Heartbeat API maintains consumer group membership and detects failures.
Version Kafka Key Changes 0 0.9.0 Initial version 1 0.10.1 Throttle time 2 0.11.0 Response before throttling 3 2.3.0 Group instance ID 4 2.4.0 Flexible versions
group_instance_id: NULLABLE_STRING
Field Type Description group_idSTRING Consumer group ID generation_idINT32 Current group generation member_idSTRING Member’s assigned ID group_instance_idNULLABLE_STRING Static membership ID
Aspect Guarantee Frequency Must send within session.timeout.ms Failure detection Missing heartbeats trigger rebalance Rebalance signal REBALANCE_IN_PROGRESS indicates pending rebalance
Error Code Meaning Recovery NONE Success Continue heartbeating REBALANCE_IN_PROGRESS Rebalance started Rejoin group ILLEGAL_GENERATION Stale generation Rejoin group UNKNOWN_MEMBER_ID Member removed Rejoin group FENCED_INSTANCE_ID Static member fenced Exit or rejoin
The SyncGroup API distributes partition assignments after a successful rebalance.
Version Kafka Key Changes 0 0.9.0 Initial version 1 0.10.1 Throttle time 2 0.11.0 Response improvements 3 2.3.0 Group instance ID 4 2.4.0 Flexible versions 5 2.7.0 Protocol type/name
group_instance_id: NULLABLE_STRING
protocol_type: NULLABLE_STRING
protocol_name: NULLABLE_STRING
assignments: [Assignment]
Field Type Description assignmentsARRAY Partition assignments (leader only)
protocol_type: NULLABLE_STRING
protocol_name: NULLABLE_STRING
Field Type Description assignmentBYTES Member’s partition assignment
The assignment bytes follow a protocol-specific format. For the “consumer” protocol:
ConsumerProtocolAssignment =>
assigned_partitions: [TopicPartition]
Aspect Guarantee Leader responsibility Only leader must include assignments Follower behavior Non-leaders must send empty assignments Atomicity All members receive assignments when coordinator responds Consistency Same assignment for same generation
The LeaveGroup API gracefully removes members from a consumer group.
Version Kafka Key Changes 0 0.9.0 Initial version 1 0.10.1 Throttle time 2 0.11.0 Response before throttling 3 2.3.0 Batch member removal + group instance ID 4 2.4.0 Flexible versions 5 3.0.0 Reason field (KIP-800)
members: [MemberIdentity]
group_instance_id: NULLABLE_STRING
members: [MemberResponse]
group_instance_id: NULLABLE_STRING
Aspect Guarantee Immediate effect Member removed immediately Rebalance trigger Remaining members notified via heartbeat Static members May leave without triggering immediate rebalance
The OffsetCommit API stores consumer offsets in the __consumer_offsets topic.
Version Kafka Key Changes 0 0.8.1 Initial version (removed in 4.0) 1 0.8.2 Commit timestamp (removed in 4.0) 2 0.9.0 Retention time (4.0 baseline) 3 0.11.0 Throttle time 5 2.1.0 Retention time removed 6 2.1.0 Leader epoch 7 2.3.0 Group instance ID 8 2.4.0 Flexible versions 9 3.5.0 Consumer group protocol (KIP-848) 10 4.0.0 Topic IDs
generation_id_or_member_epoch: INT32
group_instance_id: NULLABLE_STRING
committed_leader_epoch: INT32
committed_metadata: NULLABLE_STRING
Topic names are used through v9; v10+ uses topic_id instead.
Field Type Description generation_id_or_member_epochINT32 Group generation (classic) or member epoch (consumer protocol) committed_offsetINT64 Offset to commit committed_leader_epochINT32 Leader epoch of committed offset committed_metadataNULLABLE_STRING Application metadata
Aspect Guarantee Durability Committed to replicated __consumer_offsets topic Visibility Available immediately after successful commit Generation check Must match current generation (if group member) Retention Subject to offsets.retention.minutes
Error Code Retriable Cause Recovery ILLEGAL_GENERATION ❌ Stale generation Rejoin group UNKNOWN_MEMBER_ID ❌ Not a group member Rejoin group OFFSET_METADATA_TOO_LARGE ❌ Metadata too large Reduce metadata GROUP_AUTHORIZATION_FAILED ❌ No Read permission Check ACLs
The OffsetFetch API retrieves committed offsets for a consumer group.
Version Kafka Key Changes 0 0.8.1 Initial version (removed in 4.0) 1 0.8.2 Kafka-stored offsets (4.0 baseline) 2 0.10.2 All partitions + top-level error 3 0.11.0 Throttle time 5 2.1.0 Leader epoch 6 2.4.0 Flexible versions 7 2.5.0 Require stable 8 3.0.0 Multiple groups 9 3.5.0 Consumer group protocol (KIP-848) 10 4.0.0 Topic IDs
partition_indexes: [INT32]
member_id: NULLABLE_STRING
Field Type Description topicsARRAY Topics/partitions to fetch (null for all) require_stableBOOLEAN If true, unstable offsets return a retriable error
committed_leader_epoch: INT32
metadata: NULLABLE_STRING
Field Type Description committed_offsetINT64 Last committed offset (-1 if none) committed_leader_epochINT32 Leader epoch of committed offset metadataNULLABLE_STRING Application metadata
Aspect Guarantee Consistency Returns latest committed offset No offset Returns -1 if no offset committed require_stable With true, waits for pending transactions
The DescribeGroups API retrieves detailed information about consumer groups.
Version Kafka Key Changes 0 0.9.0 Initial version 1 0.10.1 Throttle time 2 0.11.0 Response improvements 3 2.3.0 Authorized operations 4 2.4.0 KIP-345 5 2.4.0 Flexible versions 6 3.9.0 GROUP_ID_NOT_FOUND (KIP-1043)
include_authorized_operations: BOOLEAN
DescribeGroupsResponse =>
authorized_operations: INT32
group_instance_id: NULLABLE_STRING
Field Type Description group_stateSTRING Current group state protocol_typeSTRING Protocol type (e.g., “consumer”) protocol_dataSTRING Selected protocol name member_assignmentBYTES Current partition assignment
State Description EmptyNo active members PreparingRebalanceRebalance in progress CompletingRebalanceWaiting for SyncGroup StableActive and stable DeadGroup being deleted
The ListGroups API lists all consumer groups on a broker.
Version Kafka Key Changes 0 0.9.0 Initial version 1 0.10.1 Throttle time 3 2.4.0 Flexible versions 4 2.6.0 States filter (KIP-518) 5 3.5.0 Types filter (KIP-848)
Field Type Description states_filterARRAY Filter by group states types_filterARRAY Filter by group types
The DeleteGroups API deletes consumer groups.
Version Kafka Key Changes 0 1.1.0 Initial version 1 2.0.0 Response improvements 2 2.4.0 Flexible versions
Aspect Guarantee Precondition Group must be Empty or Dead Atomicity Each group deletion is independent Effect Removes group and all committed offsets
The OffsetDelete API deletes committed offsets for a group and set of partitions.
Version Kafka Key Changes 0 0.11.0 Initial version
Complete consumer flow from startup through the consume loop Application Consumer Any Broker Coordinator Partition Leader Application Application Consumer Consumer Any Broker Any Broker Coordinator Coordinator Partition Leader Partition Leader Startup new KafkaConsumer() MetadataRequest MetadataResponse FindCoordinatorRequest(group_id) FindCoordinatorResponse(coordinator) Join Group JoinGroupRequest JoinGroupResponse(generation, leader) SyncGroupRequest SyncGroupResponse(assignment) Fetch Offsets OffsetFetchRequest OffsetFetchResponse(offsets) Consume Loop loop [poll()] Heartbeat (in parallel) HeartbeatRequest HeartbeatResponse Fetch (in parallel) FetchRequest FetchResponse(records) OffsetCommitRequest OffsetCommitResponse Shutdown LeaveGroupRequest LeaveGroupResponse