Distributed Lock Service  ·  View 13 of 26  ·  4 · Data

Token Space Across Restore

Why a restored cluster cannot issue a token it has issued before, by construction rather than by runbook.

Editable source SVG draw.io All views
Serving epoch E grants compare epoch Snapshot every 30 min Quorum destroyed Restore new cluster ID Sealed ID ≠ epoch record Advance to E+1 one committed Txn Token space (epoch, revision) etcdutl snapshot disaster etcdutl restore grants refused gated job first grant Token Space Across Restore — Why It Never Regresses Application we own Data store Risk / gap Decision point Security / platform v 1.0 · owner Platform Architecture · date 2026-09

Decisions

  • The epoch record stores the etcd cluster ID it was minted for. etcdutl snapshot restore always creates a new cluster ID, so a restored cluster is detectably not the one that issued the old tokens.
  • Every grant transaction compares the epoch key. An arbiter that sees a cluster ID mismatch in the response header refuses to serve, and the only accepted write is the epoch advance.
  • The advance is one transaction that sets epoch E+1 bound to the new cluster ID and deletes every restored hold. Holders from before the disaster re-acquire and get tokens above anything they could have seen.

Why not a runbook step

  • The restore happens during the worst hour of someone's year. A step that must be remembered under that pressure will be skipped once, and once is a duplicate token. A service that cannot start serving without the step cannot skip it.

What it costs

  • After a restore every lock is released at once and every holder reacquires. Expect a reacquisition storm; jittered reconnect in the client is what keeps it survivable.