hashicorp/nomad · error
leadership transfer not supported with Raft version lower th
Error message
leadership transfer not supported with Raft version lower than 3
What it means
When transferring leadership to a specific peer, Nomad retries raft.LeadershipTransferToServer; raft.ErrUnsupportedProtocol means the target cluster's Raft protocol version is below 3, which does not support leadership transfer at all. Nomad converts this into a non-retried terminal error.
Source
Thrown at nomad/leader.go:208
}
// "cannot transfer leadership to itself"
// Handled at top of function, but reapplied here to prevent retrying if
// it occurs while we are retrying
if err.Error() == "cannot transfer leadership to itself" {
s.logger.Debug("leadership transfer to current leader is a no-op")
return nil
}
// ErrRaftShutdown: Don't retry if raft is shut down.
if err == raft.ErrRaftShutdown {
return err
}
// ErrUnsupportedProtocol: Don't retry if the Raft version doesn't
// support leadership transfer since this will never succeed.
if err == raft.ErrUnsupportedProtocol {
return fmt.Errorf("leadership transfer not supported with Raft version lower than 3")
}
// ErrEnqueueTimeout: This seems to be the valid time to retry.
s.logger.Error("failed to transfer leadership attempt, will retry",
"attempt", i,
"retry_limit", retryCount,
"error", err,
)
lastError = err
}
return fmt.Errorf("failed to transfer leadership in %d attempts. last error: %w", retryCount, lastError)
}
func (s *Server) leadershipTransfer() error {
retryCount := 3
for i := range retryCount {
err := s.raft.LeadershipTransfer().Error()
if err == nil {View on GitHub (pinned to 482b49bf1a)
Solutions
- Raise the server's raft_protocol config to 3 (or higher) on all servers and restart the agents.
- Restart Nomad servers one at a time to roll the Raft protocol version across the cluster.
- If upgrade isn't possible, trigger a normal leader step-down (restart the leader) instead of an explicit transfer.
Example fix
// before (agent config)
server { raft_protocol = 2 }
// after
server { raft_protocol = 3 } Defensive patterns
Strategy: validation
Validate before calling
if cfg.Server.RaftProtocol < 3 {
return fmt.Errorf("leadership transfer requires raft_protocol >= 3 (current: %d)", cfg.Server.RaftProtocol)
} Try / catch
if err := transferLeadership(peer); err != nil {
if strings.Contains(err.Error(), "not supported with Raft version lower than 3") {
return fmt.Errorf("upgrade raft_protocol on all servers before transferring leadership")
}
return err
} Prevention
- Run raft_protocol 3+ on every Nomad server.
- Check Raft protocol version via `nomad operator raft list-peers` before maintenance transfers.
- During version upgrades, roll servers so protocol versions are uniform.
- Fall back to leader restart for step-down on legacy clusters.
When it happens
Trigger: TransferLeadershipToPeer invoked (e.g. `nomad server force-leave`-driven step-down, operator-triggered transfer, or leaderLoop fallback) against a Raft setup where raft protocol version < 3 (config `raft_protocol` set to 1 or 2).
Common situations: Clusters upgraded from very old Nomad versions still running raft_protocol = 2; mixed-version clusters where a server was configured with a lower Raft protocol; operators forcing leadership handoff during maintenance on legacy nodes.
Related errors
- failed to transfer leadership in %d attempts. last error: %w
- failed to reset heartbeat since server is not leader
- unsupported minimum common raft protocol version
- must provide peer id or address
- cluster ID not ready yet
AI-assisted analysis of hashicorp/nomad@482b49bf1a (2026-09-04).
Data as JSON: /api/errors/20696677ee47f3a1.
Report an issue: GitHub.