Skip to content

[v25.3.x] raft: refresh election timer on recovery-path append_entries (pre-vote livelock) - #31255

Merged
bharathv merged 1 commit into
redpanda-data:v25.3.xfrom
vbotbuildovich:ai-backport-pr-30817-v25.3.x-1784821079
Aug 11, 2026
Merged

[v25.3.x] raft: refresh election timer on recovery-path append_entries (pre-vote livelock)#31255
bharathv merged 1 commit into
redpanda-data:v25.3.xfrom
vbotbuildovich:ai-backport-pr-30817-v25.3.x-1784821079

Conversation

@vbotbuildovich

Copy link
Copy Markdown
Collaborator

Backport of PR #30817

  • Command: git cherry-pick -x 81f445b eb137bf
  • Commits backported: 2
  • Conflicts resolved: 0
  • Commits skipped (already on target): 1
  • Backport branch: ai-backport-pr-30817-v25.3.x-1784821079

Conflict details

  • eb137bf (merge commit): skipped. This is a routine "Merge branch 'dev' into fix/raft-prevote-livelock-recovery-hbeat" sync commit whose first parent is the PR's fix commit (81f445b, already applied) and whose second parent is a dev tip. Its only non-parent hunks are conflict resolutions of unrelated dev changes (src/v/cloud_storage_clients/multipart_upload.cc and tests/rptest/scale_tests/many_partitions_test.py), which belong to dev rather than to this PR. The PR's actual fix is entirely contained in 81f445b (src/v/raft/consensus.cc), so the merge carries no PR-specific change to backport.

Fixes: #31254,

A follower that is behind a live leader can get stuck in a perpetual
pre-vote storm. `should_skip_vote` suppresses elections only while
`_hbeat` (last leader contact) is within one election timeout, but in
`do_append_entries` the `_hbeat` refresh lives on the successful
batch-append path (a deferred update). The two early returns that fire
when the follower is behind, log gap (prev_log_index > last_log_offset)
and prev-log-term mismatch, call maybe_update_leader() and reply to the
leader but never refresh `_hbeat`.

So a follower in continuous contact with the current-term leader, but
unable to append because it is still being recovered, lets its election
timer expire, starts a (pre-)vote that deterministically fails the
longest-log check (log_ok=false), rearms, and repeats. The storm burns
CPU that further starves recovery, a self-reinforcing livelock that
leaves partitions under-replicated and stalls acks=all produce with
REQUEST_TIMED_OUT.

Refresh `_hbeat` as soon as an append_entries from the current-term
leader is accepted (right after maybe_update_leader), covering the
recovery early-return paths as well as the success path. This matches
the existing design intent noted in vote_request handling, where the
comment states `_hbeat` is updated by the leader. Liveness is preserved:
if the leader is actually gone, no append_entries arrive, `_hbeat` goes
stale, and elections proceed as before.

Fixes redpanda-data#30815

Signed-off-by: Steven Pall <mail@stevenpall.ca>
(cherry picked from commit 81f445b)
@vbotbuildovich vbotbuildovich added this to the v25.3.x-next milestone Jul 23, 2026
@vbotbuildovich vbotbuildovich added the kind/backport PRs targeting a stable branch label Jul 23, 2026
@nvartolomei
nvartolomei requested a review from bharathv August 11, 2026 13:06
@bharathv
bharathv merged commit c74cda6 into redpanda-data:v25.3.x Aug 11, 2026
17 checks passed
@tyson-redpanda tyson-redpanda modified the milestones: v25.3.x-next, v25.3.16 Aug 11, 2026
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

area/redpanda kind/backport PRs targeting a stable branch

Projects

None yet

Development

Successfully merging this pull request may close these issues.

4 participants