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

  1. Raise the server's raft_protocol config to 3 (or higher) on all servers and restart the agents.
  2. Restart Nomad servers one at a time to roll the Raft protocol version across the cluster.
  3. 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

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


AI-assisted analysis of hashicorp/nomad@482b49bf1a (2026-09-04). Data as JSON: /api/errors/20696677ee47f3a1. Report an issue: GitHub.