nats-io/nats-server · error
Unsafe quorum rescue applied, quorum lowered %d -> %d for %v
Error message
Unsafe quorum rescue applied, quorum lowered %d -> %d for %v
What it means
An operator-driven RescueQuorum lowered the quorum from the natural value to qn for a bounded rescueQuorumTimeout, allowing elections/commits on a degraded cluster. A timer auto-expires the rescue; while active, recalcQuorum preserves the lowered value. This is deliberately unsafe: commits may lack durable majority.
Source
Thrown at server/raft.go:1361
// If all servers are empty, this requires a cluster bootstrap.
if n.pindex == 0 {
return prev, 0, errRescueEmptyLog
}
// Cancel any previous rescue.
if n.rescue != nil {
n.rescue.Stop()
}
var t *time.Timer
t = time.AfterFunc(rescueQuorumTimeout, func() {
n.Lock()
defer n.Unlock()
// Read of t must be under the lock.
n.expireRescueLocked(t)
})
n.rescue = t
n.qn = qn
n.warn("Unsafe quorum rescue applied, quorum lowered %d -> %d for %v", prev, qn, rescueQuorumTimeout)
// Make sure an election can happen soon.
n.resetElect(randCampaignTimeout())
return prev, qn, nil
}
// expireRescueLocked runs when the rescue timeout fires and restores the natural quorum.
// Lock should be held.
func (n *raft) expireRescueLocked(t *time.Timer) {
if n.State() == Closed || n.rescue != t {
return
}
// Must clear the timer first, recalcQuorum keeps the rescued quorum
// while it sees an active rescue.
n.rescue = nil
n.recalcQuorum()
n.warn("Unsafe quorum rescue expired, quorum restored to %d", n.qn)
}View on GitHub (pinned to 3a66a489d2)
Solutions
- Restore missing peers before the rescue timeout expires to avoid split-brain risk
- Back up RAFT state before using rescue on production clusters
- Monitor for the 'rescue expired' log to know when normal quorum returned
Defensive patterns
Strategy: fallback
When it happens
Trigger: Thrown at server/raft.go:1361 when the library encounters an invalid state.
Common situations: See trigger scenarios.
AI-assisted analysis of nats-io/nats-server@3a66a489d2 (2026-09-02).
Data as JSON: /api/errors/eda15740b72cbda7.
Report an issue: GitHub.