You are viewing a plain text version of this content. The canonical link for it is here.
Posted to dev@kafka.apache.org by "sanghyeok An (Jira)" <ji...@apache.org> on 2026/10/05 12:52:00 UTC
[jira] [Created] (KAFKA-21219) Streams group dynamic member close can stall with REMAIN\_IN\_GROUP after poll timeout
sanghyeok An created KAFKA-21219:
------------------------------------
Summary: Streams group dynamic member close can stall with REMAIN\_IN\_GROUP after poll timeout
Key: KAFKA-21219
URL: https://issues.apache.org/jira/browse/KAFKA-21219
Project: Kafka
Issue Type: Bug
Reporter: sanghyeok An
Assignee: sanghyeok An
Closing a Streams group dynamic member with {{REMAIN_IN_GROUP}} can leave the close future incomplete when the poll timer has expired.
{{StreamsMembershipManager.isLeavingGroup()}} returns {{false}} for dynamic members using {{{}REMAIN_IN_GROUP{}}}, even when their state is {{PREPARE_LEAVING}} or {{{}LEAVING{}}}. Consequently, {{StreamsGroupHeartbeatRequestManager.poll()}} enters the poll timeout branch despite the member already leaving.
When the member is in {{{}LEAVING{}}}, {{onPollTimerExpired()}} attempts to transition it back to {{{}PREPARE_LEAVING{}}}, throwing:
{{IllegalStateException: Invalid state transition from LEAVING to PREPARE_LEAVING}}
This exception occurs before a heartbeat request is generated and prevents the normal path from skipping the leave heartbeat and completing the close future.
*Reproduction conditions*
# Join a Streams group as a dynamic member without configuring {{{}group.instance.id{}}}.
# Allow the application poll interval to exceed {{{}max.poll.interval.ms{}}}.
# Before the heartbeat manager processes the poll timeout, process a close request with {{{}REMAIN_IN_GROUP{}}}, transitioning the member to {{{}LEAVING{}}}.
# On the next heartbeat manager {{{}poll(){}}}, the invalid state transition exception occurs.
*Expected behavior*
Poll timeout handling should not initiate another leave operation while the member is already preparing to leave or leaving.
For a dynamic member closing with {{{}REMAIN_IN_GROUP{}}}, once the member reaches {{{}LEAVING{}}}, the client should skip the leave heartbeat, transition to {{{}UNSUBSCRIBED{}}}, and complete the close future normally.
While in {{{}PREPARE_LEAVING{}}}, regular heartbeats may continue until the pending callback completes.
--
This message was sent by Atlassian Jira
(v8.20.10#820010)