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)