Skip to content

Non-atomic vote persistence in handleRequestVoteRequest #1241

Description

@Qian-Cheng-nju

Describe the bug

handleRequestVoteRequest() does not check the return value of metaStorage.setVotedFor() at NodeImpl.java#L1860. If the disk write fails but the process survives, the response is still granted=true because the in-memory votedId was already set at L1859 before the write. After restart the vote is lost, allowing a different candidate to be granted in the same term.

This is the only call site that uses setVotedFor() alone. All other call sites use setTermAndVotedFor().

Expected behavior

A node should vote for at most one candidate per term, even after a write failure and restart.

Actual behavior

If setVotedFor() fails (I/O error), the response is still granted=true. After restart, the node grants a vote to a different candidate in the same term.

Steps to reproduce

See #1242. The test makes the meta directory read-only before setVotedFor() is called, causing a real I/O failure through the full reportIOError()node.onError() path.

Minimal yet complete reproducer code (or GitHub URL to code)

See #1242.

Environment

  • SOFAJRaft version: master
  • JVM version: 21
  • OS version: Linux

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions