nats-io/nats-server · error
Not granting vote for %q, could not persist term and vote: %
Error message
Not granting vote for %q, could not persist term and vote: %v
What it means
A candidate/leader could not persist its term+vote before granting a vote (writeTermVote failed). Per Raft safety the vote is simply not granted — the candidate's up-to-date log alone is not sufficient — and the requester must obtain a quorum elsewhere or in a later round.
Source
Thrown at server/raft.go:5652
voteOk := n.vote == noVote || n.vote == vr.candidate
// If we have an empty log, but are initializing.
if voteOk && vresp.empty && n.initializing {
// Reset notion of having an empty log if we're voting during initialization/scale up.
// Ensures they only need quorum, and not need to hear from all servers.
vresp.empty = false
}
// Other server's log needs to be equal or more up-to-date than ours.
if voteOk && (vr.lastTerm > n.pterm || vr.lastTerm == n.pterm && vr.lastIndex >= n.pindex) {
// Persist our vote before granting it. Raft requires the vote to be durable before
// we respond, otherwise a restart could forget the vote and let us grant a second
// vote in the same term, which would break election safety.
n.term = vr.term
n.vote = vr.candidate
if err := n.writeTermVote(); err != nil {
n.vote = noVote
n.warn("Not granting vote for %q, could not persist term and vote: %v", n.group, err)
} else {
vresp.granted = true
n.resetElectionTimeout()
}
} else if n.vote == noVote && n.State() != Candidate {
// We have a more up-to-date log, and haven't voted yet.
// Start campaigning earlier, but only if not candidate already, as that would short-circuit us.
n.resetElect(randCampaignTimeout())
}
// Term might have changed, make sure response has the most current
vresp.term = n.term
n.Unlock()
n.sendReply(vr.reply, vresp.encode())
return nilView on GitHub (pinned to 3a66a489d2)
Solutions
- Fix the underlying persistence failure (disk full, permissions, I/O error)
- The requester will retry or win via other voters; no manual intervention needed for transient errors
- Recurring failures on all nodes prevent elections — repair storage first
Defensive patterns
Strategy: fallback
When it happens
Trigger: Thrown at server/raft.go:5652 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/31059488353d10f6.
Report an issue: GitHub.