redis/redis-py · error · ConnectionError

Failed to subscribe to cluster nodes: {', '.join(failed_node

Error message

Failed to subscribe to cluster nodes: {', '.join(failed_nodes)}

What it means

Raised as redis.exceptions.ConnectionError by ClusterKeyspaceNotifications.refresh_subscriptions (redis/keyspace_notifications.py:2164). After a cluster topology change (or a broken pubsub connection) the manager re-subscribes every new primary to the registered patterns/channels; if one or more nodes fail to subscribe, they are cleaned up and the list of failed node names is aggregated into a single error raised after all nodes are attempted.

Source

Thrown at redis/keyspace_notifications.py:2164

            new_nodes = set(current_primaries.keys()) - set(self._node_pubsubs.keys())
            failed_nodes: list[str] = []
            for node_name in new_nodes:
                node = current_primaries[node_name]
                pubsub = self._ensure_node_pubsub(node)

                try:
                    if self._subscribed_patterns:
                        pubsub.psubscribe(**self._subscribed_patterns)
                    if self._subscribed_channels:
                        pubsub.subscribe(**self._subscribed_channels)
                except Exception:
                    # Subscription failed - remove from dict so retry is possible
                    self._cleanup_node(node_name)
                    failed_nodes.append(node_name)

            # Raise after attempting all nodes so we don't skip any
            if failed_nodes:
                raise ConnectionError(
                    f"Failed to subscribe to cluster nodes: {', '.join(failed_nodes)}"
                )

    def close(self):
        """Close all pubsub connections and clean up resources."""
        self._closed = True
        for node_name in list(self._node_pubsubs.keys()):
            self._cleanup_node(node_name)
        self._subscribed_patterns.clear()
        self._subscribed_channels.clear()

View on GitHub (pinned to da03cdc7e8)

Solutions

  1. Catch ConnectionError and retry — refresh_subscriptions is idempotent and will re-attempt the failed nodes on the next call.
  2. Verify cluster health (CLUSTER NODES) and that all primaries are reachable before relying on notifications.
  3. Ensure the ACL/user used by the client has SUBSCRIBE/PSUBSCRIBE permission on every primary.
  4. Check network connectivity/firewall between the client and each primary node listed in the error.
  5. If a node is permanently down, remove it from the cluster or wait for failover to promote a reachable replica.

Example fix

// before
ckn.refresh_subscriptions()  # may raise mid-failover

// after
import time
from redis.exceptions import ConnectionError
for _ in range(5):
    try:
        ckn.refresh_subscriptions()
        break
    except ConnectionError:
        time.sleep(1)  # backoff; next call re-attempts failed nodes
Defensive patterns

Strategy: retry

Try / catch

import time
from redis.exceptions import ConnectionError
for attempt in range(max_refresh_attempts):
    try:
        ckn.refresh_subscriptions()
        break
    except ConnectionError as e:
        # failed node names are in the message; will be re-attempted next call
        time.sleep(backoff_for(attempt))
else:
    raise

Prevention

When it happens

Trigger: A cluster topology refresh (failover, resharding, node add/remove) or a dropped pubsub connection that triggers refresh_subscriptions(), where subscribe()/psubscribe() on at least one primary node raises. Called automatically on connection errors and topology changes, or manually.

Common situations: A primary node is temporarily unreachable during failover; network partition isolating some nodes; overloaded node rejecting pubsub subscriptions; ACL denying SUBSCRIBE on a node; nodes restarting mid-refresh.

Related errors


AI-assisted analysis of redis/redis-py@da03cdc7e8 (2026-08-04). Data as JSON: /data/errors/bddd87fbd707983d.json. Report an issue: GitHub.