Skip to content

KAFKA-20731: Streams: transitToUpdateStandby is called without checking ACTIVE_RESTORING, crashing the state updater thread#22864

Open
arnabnandy7 wants to merge 1 commit into
apache:trunkfrom
arnabnandy7:fix/state-updater-crash
Open

KAFKA-20731: Streams: transitToUpdateStandby is called without checking ACTIVE_RESTORING, crashing the state updater thread#22864
arnabnandy7 wants to merge 1 commit into
apache:trunkfrom
arnabnandy7:fix/state-updater-crash

Conversation

@arnabnandy7

Copy link
Copy Markdown

Fixes KAFKA-20731.

DefaultStateUpdater could call the non-idempotent ChangelogReader#transitToUpdateStandby method while the changelog reader was already in STANDBY_UPDATING. This could happen after all updating standby tasks were paused or removed because the empty-task state did not transition the reader back to ACTIVE_RESTORING. Adding or resuming a standby task afterward attempted the standby transition again, throwing an IllegalStateException and terminating the state updater thread.

This change centralizes changelog reader state transitions in DefaultStateUpdater and enforces the following invariants:

  • When there are no updating tasks, the reader is in ACTIVE_RESTORING.
  • When only standby tasks are updating, the reader transitions to STANDBY_UPDATING only if it is currently restoring active tasks.
  • The existing non-idempotent contract and defensive exception in StoreChangelogReader#transitToUpdateStandby remain unchanged.

The transition helper is invoked after task additions, resumptions, pauses, removals, failures, and active restoration completion so that the reader state remains consistent with the updating task set.

The DefaultStateUpdaterTest changelog reader mock now models the actual reader state transitions. This allows the standby pause/resume regression test to fail if transitToUpdateStandby is invoked twice without an intervening transition back to active restoration.

Testing:

gradle streams:test \
  --tests org.apache.kafka.streams.processor.internals.DefaultStateUpdaterTest \
  --no-daemon \
  --console=plain

All 87 DefaultStateUpdaterTest tests passed. The test execution also completed checkstyleMain, checkstyleTest, and spotbugsMain successfully.

Signed-off-by: Arnab Nandy <arnab_nandy7@yahoo.com>
@github-actions github-actions Bot added triage PRs from the community streams small Small PRs labels Jul 18, 2026
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

small Small PRs streams triage PRs from the community

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant