go-redis/redis · critical
redis: cluster has no nodes
Error message
redis: cluster has no nodes
What it means
errClusterNoNodes (osscluster.go:37) is returned when a ClusterClient has zero known nodes to route to. It is produced at seven sites: cluster address list being empty after Close/teardown (osscluster.go:701), keyless command routing with no masters (osscluster.go:2949), arbitrary/all-node/all-shard fan-out with empty state (osscluster_router.go:76,92,106,317), and topology-load paths (osscluster.go:1866,1912). It means the cluster client has no usable topology.
Source
Thrown at osscluster.go:37
"time"
"github.com/redis/go-redis/v9/auth"
"github.com/redis/go-redis/v9/internal"
"github.com/redis/go-redis/v9/internal/hashtag"
"github.com/redis/go-redis/v9/internal/otel"
"github.com/redis/go-redis/v9/internal/pool"
"github.com/redis/go-redis/v9/internal/proto"
"github.com/redis/go-redis/v9/internal/routing"
"github.com/redis/go-redis/v9/maintnotifications"
"github.com/redis/go-redis/v9/push"
)
const (
minLatencyMeasurementInterval = 10 * time.Second
)
var (
errClusterNoNodes = errors.New("redis: cluster has no nodes")
errNoWatchKeys = errors.New("redis: Watch requires at least one key")
errWatchCrosslot = errors.New("redis: Watch requires all keys to be in the same slot")
)
// ClusterOptions are used to configure a cluster client and should be
// passed to NewClusterClient.
type ClusterOptions struct {
// A seed list of host:port addresses of cluster nodes.
Addrs []string
// ClientName will execute the `CLIENT SETNAME ClientName` command for each conn.
ClientName string
// NewClient creates a cluster node client with provided name and options.
// If NewClient is set by the user, the user is responsible for handling maintnotifications upgrades and push notifications.
NewClient func(opt *Options) *Client
// The maximum number of retries before giving up. Command is retriedView on GitHub (pinned to 36d97525cd)
Solutions
- Provide at least one reachable seed node in ClusterOptions.Addrs.
- Verify the seed node is up and reachable (telnet/redis-cli CLUSTER NODES) from the client host.
- Do not issue commands on a client after Close(); construct a fresh one.
- Check that the cluster actually has masters (CLUSTER NODES); if all masters are down, restore them before retrying.
- Add a Dialer with retries/backoff and confirm network/DNS to the seed resolves.
Example fix
// before
c := redis.NewClusterClient(&redis.ClusterOptions{Addrs: nil})
// any command -> errClusterNoNodes
// after
c := redis.NewClusterClient(&redis.ClusterOptions{
Addrs: []string{"redis-node-0:6379", "redis-node-1:6379", "redis-node-2:6379"},
}) Defensive patterns
Strategy: validation
Validate before calling
if len(clusterOpts.Addrs) == 0 {
return fmt.Errorf("cluster client requires at least one seed node address")
}
// optionally liveness-check a seed before constructing the client
for _, a := range clusterOpts.Addrs {
if c, err := net.DialTimeout("tcp", a, 2*time.Second); err == nil {
c.Close()
break
}
} Try / catch
err := c.Ping(ctx).Err()
if errors.Is(err, redis.Nil) == false && err != nil {
if strings.Contains(err.Error(), "cluster has no nodes") {
// seeds empty or unreachable: reconfigure Addrs and recreate client
}
} Prevention
- Always pass >=1 reachable seed node in ClusterOptions.Addrs.
- Don't issue commands after Close().
- Add health checks / retries on the seed dialer.
- Confirm the cluster has masters via CLUSTER NODES when debugging.
When it happens
Trigger: Issuing a command on a ClusterClient whose Addrs list is empty, or after the cluster state failed to load (all nodes unreachable at startup), or after the client was Closed (clusterNodes closed, addrs emptied). Keyless commands (no slot) hit it when state.Masters is empty; fan-out commands (KEYS, DBSIZE across nodes) hit it when state has no nodes at all.
Common situations: Constructing NewClusterClient(&ClusterOptions{Addrs: nil}); all seed nodes unreachable so the initial CLUSTER SLOTS fails and state is empty; using a client after Close(); a cluster that lost all its masters; misconfigured load balancer returning nothing for the seed address.
Related errors
- redis: no valid results to aggregate for max operation
- redis: no valid results to aggregate for logical AND operati
- redis: no valid results to aggregate for logical OR operatio
- routing: unknown response_policy %q
- redis: invalid URL scheme: %s
AI-assisted analysis of go-redis/redis@36d97525cd (2026-08-06).
Data as JSON: /data/errors/7903ba1963c68876.json.
Report an issue: GitHub.