go-redis/redis · error

got %d elements in cluster info address, expected 2, 3, or 4

Error message

got %d elements in cluster info address, expected 2, 3, or 4

What it means

Thrown by ClusterSlotsCmd.readReply (command.go:4710) when a per-node address sub-array inside a CLUSTER SLOTS entry does not have 2, 3, or 4 elements (ip/port, optional node-id, optional hostname). The parser must know the exact shape to consume the array correctly, so any other length aborts parsing. Note: the format verb prints `n` (the outer entry length) rather than the sub-array length `nn` due to a long-standing bug in the format arguments, so the reported number can be misleading.

Source

Thrown at command.go:4710

		if err != nil {
			return err
		}

		end, err := rd.ReadInt()
		if err != nil {
			return err
		}

		// subtract start and end.
		nodes := make([]ClusterNode, n-2)

		for j := 0; j < len(nodes); j++ {
			nn, err := rd.ReadArrayLen()
			if err != nil {
				return err
			}
			if nn < 2 || nn > 4 {
				return fmt.Errorf("got %d elements in cluster info address, expected 2, 3, or 4", n)
			}

			ip, err := rd.ReadString()
			if err != nil {
				return err
			}

			port, err := rd.ReadString()
			if err != nil {
				return err
			}

			nodes[j].Addr = net.JoinHostPort(ip, port)

			if nn >= 3 {
				id, err := rd.ReadString()
				if err != nil {
					return err

View on GitHub (pinned to 36d97525cd)

Solutions

  1. Inspect raw CLUSTER SLOTS output with redis-cli and confirm every node tuple is [ip, port] or [ip, port, id] or [ip, port, id, hostname].
  2. Remove any RESP-rewriting proxy from the data path, or switch to a standalone Client if the target is not a real cluster.
  3. Upgrade go-redis for stricter/tolerant parsing and CLUSTER SHARDS support.
  4. Retry once if the error appears during a failover/reshard window.
Defensive patterns

Strategy: validation

Validate before calling

// Confirm CLUSTER SLOTS node tuples are well-formed before relying on them.
raw, err := client.ClusterSlots(ctx).Result()
if err != nil { return err }
for _, s := range raw {
    for _, n := range s.Nodes {
        if n.Addr == "" { return fmt.Errorf("malformed cluster node address") }
    }
}

Try / catch

if _, err := client.ClusterSlots(ctx).Result(); err != nil {
    // retry after topology settles, or fall back to CLUSTER SHARDS / ReloadState
    _ = client.ReloadState(ctx)
    return err
}

Prevention

When it happens

Trigger: client.ClusterSlots(ctx) where a node-address sub-array is malformed: a non-standard Redis fork, a proxy rewriting CLUSTER SLOTS, or a corrupted/partial RESP frame.

Common situations: Using a Redis-compatible proxy or service that emits address arrays of an unexpected length; transient corruption during network instability or failover.

Related errors


AI-assisted analysis of go-redis/redis@36d97525cd (2026-08-06). Data as JSON: /data/errors/8823105c94b871ab.json. Report an issue: GitHub.