Skip to content

ArcadeStateMachine.takeSnapshot() reports a compaction index to Ratis but never writes a snapshot file β€” log purge can permanently orphan applied stateΒ #4829

Closed

Description

@ruispereira

Affected version: 26.6.1
Component: ArcadeStateMachine.takeSnapshot / reinitialize
Severity: HIGH

Summary

takeSnapshot() returns lastAppliedIndex β€” the Ratis contract for "state up to
this index is durable, you may purge the log" β€” but writes no snapshot file.
SimpleStateMachineStorage.getLatestSnapshot() discovers snapshots by scanning for
snapshot.<term>_<index> files, so it always returns null. With auto-snapshot +
purgeUptoSnapshotIndex enabled, Ratis purges log entries up to the returned
index even though no snapshot exists.

Code

ArcadeStateMachine.java:360-367 (return currentIndex; no file written),
:189-225 (reinitialize β†’ getLatestSnapshot() null β†’ lastAppliedIndex=-1);
RaftPropertiesBuilder.java:84,89-95 (auto-trigger + purge enabled).

Impact

After log purge + restart, the node restores lastAppliedIndex = -1 and Ratis
replays from the start of a log whose entries were purged β†’ cannot self-recover,
forced into full snapshot download or divergence. The reinitialize gap-detection
branch is effectively dead code since getLatestSnapshot() is always null. The
hand-rolled .raft/applied-index is used only for comparison, never to seed
lastAppliedIndex.

Suggested fix

Persist a real snapshot marker file via storage at (term,index) in
takeSnapshot(); or seed lastAppliedIndex from readPersistedAppliedIndex()
when getLatestSnapshot() is null (and make that file durable β€” see HA-27);
otherwise do not enable purgeUptoSnapshotIndex.

Activity

  1. self-assigned this
    on Jun 30, 2026
  2. added theissue type on Jun 30, 2026
  3. added this to the 26.7.1 milestone on Jun 30, 2026
  4. added a commit that references this issue on Jun 30, 2026
  5. lvca commented on Jun 30, 2026

    @lvca
    Member

    Fixed

  6. added a commit that references this issue on Aug 14, 2026
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Metadata

Metadata

Assignees

Labels

Type

Projects

No projects

    Milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions