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 nil

View on GitHub (pinned to 3a66a489d2)

Solutions

  1. Fix the underlying persistence failure (disk full, permissions, I/O error)
  2. The requester will retry or win via other voters; no manual intervention needed for transient errors
  3. 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.