googleapis/mcp-toolbox · error

unable to connect to redis cluster

Error message

unable to connect to redis cluster: %s

What it means

This error wraps the underlying failure returned by go-redis when a Redis Cluster client cannot ping any shard after connecting. The toolbox creates a redis.UniversalClient in cluster mode and calls ForEachShard with a Ping; if any shard fails to respond, initialization of the source aborts. The wrapped error reveals the true cause (auth, DNS, TLS, timeout).

Solutions

  1. Verify each address in the Redis source config is a reachable cluster node: `redis-cli -h <host> -p <port> ping` from the toolbox host.
  2. If the cluster requires auth, set `username`/`password` fields correctly (Redis 6+ ACL users need username).
  3. If TLS is enabled on the cluster, configure `useServerCA` or `tlsCa` correctly; disable TLS only if the server is plaintext.
  4. Check for firewall/NAT issues: cluster clients must reach every node's announced IP:port, not just the seed node.
  5. Run `cluster info` / `cluster nodes` on the cluster to confirm it is up and slots are covered.

Example fix

// before
sources:
  my-redis:
    kind: redis
    addresses: ["localhost:7000"]
    clusterMode: true
// after
sources:
  my-redis:
    kind: redis
    addresses: ["redis-node-1:6379", "redis-node-2:6379", "redis-node-3:6379"]
    clusterMode: true
    password: ${REDIS_PASSWORD}
Defensive patterns

Strategy: validation

Validate before calling

// Before configuring the toolbox source, verify every cluster node answers PING
for addr in "${REDIS_NODES[@]}"; do
  host=${addr%%:*}; port=${addr##*:}
  redis-cli -h "$host" -p "$port" --no-auth-warning ping || echo "unreachable: $addr"
done

Prevention

When it happens

Trigger: Redis source configured with clusterMode=true; Initialize calls initRedisClient; clusterClient.ForEachShard(ctx, ping) fails on one or more shards due to unreachable nodes, refused TCP connection, auth failure, or TLS handshake error.

Common situations: Wrong cluster node addresses or ports in the `addresses` field; cluster nodes behind NAT/firewall not reachable; Redis requirepass/ACL password mismatch; self-signed certs not matching server-ca/TLS config; cluster slots not yet assigned on a freshly created cluster.

Understand the failure class

Background: ECONNREFUSED and "connection refused" / "could not connect to server" errors: what they mean and how to fix them — this error's family across 44 libraries.

Related errors


AI-assisted analysis of googleapis/mcp-toolbox@8cc6e09de2 (2026-09-05). Data as JSON: /api/errors/229cf2469d07672e. Report an issue: GitHub.

Appendix: source

Thrown at internal/sources/redis/redis.go:127

	var err error
	if r.ClusterEnabled {
		// Create a new Redis Cluster client
		clusterClient := redis.NewClusterClient(&redis.ClusterOptions{
			Addrs: r.Address,
			// PoolSize applies per cluster node and not for the whole cluster.
			PoolSize:                   10,
			ConnMaxIdleTime:            60 * time.Second,
			MinIdleConns:               1,
			CredentialsProviderContext: authFn,
			Username:                   r.Username,
			Password:                   r.Password,
			TLSConfig:                  tlsConfig,
		})
		err = clusterClient.ForEachShard(ctx, func(ctx context.Context, shard *redis.Client) error {
			return shard.Ping(ctx).Err()
		})
		if err != nil {
			return nil, fmt.Errorf("unable to connect to redis cluster: %s", err)
		}
		client = clusterClient
		return client, nil
	}

	// Create a new Redis client
	standaloneClient := redis.NewClient(&redis.Options{
		Addr:                       r.Address[0],
		PoolSize:                   10,
		ConnMaxIdleTime:            60 * time.Second,
		MinIdleConns:               1,
		DB:                         r.Database,
		CredentialsProviderContext: authFn,
		Username:                   r.Username,
		Password:                   r.Password,
		TLSConfig:                  tlsConfig,
	})
	_, err = standaloneClient.Ping(ctx).Result()

View on GitHub (pinned to 8cc6e09de2)