redis/redis-py · error · NotImplementedError

CLUSTER FLUSHSLOTS is intentionally not implemented in the…

Error message

CLUSTER FLUSHSLOTS is intentionally not implemented in the client.

What it means

RedisCluster.cluster_flushslots() is a stub that always raises NotImplementedError. The method exists on the cluster commands surface (inherited shape) but the client intentionally does not implement CLUSTER FLUSHSLOTS, because flushing slots from a client is a destructive cluster-administration operation that should be performed via redis-cli or direct node administration, not through this driver.

Solutions

  1. Do not call cluster_flushslots() from this client; run `CLUSTER FLUSHSLOTS` via redis-cli against the specific node if you truly need it.
  2. For clearing data, use FLUSHDB/FLUSHALL on individual nodes, or bring the cluster down and re-create it.
  3. If you must call it from Python, open a direct Connection to the target node and run execute_command('CLUSTER FLUSHSLOTS') on that raw connection.

Example fix

# before
client.cluster_flushslots()
# after - use a raw node connection if absolutely required
from redis import Redis
Redis(host='node-host', port=7000).execute_command('CLUSTER FLUSHSLOTS')
Defensive patterns

Strategy: type-guard

Validate before calling

def safe_cluster_flushslots(client):
    if type(client).__name__ in ('RedisCluster', 'AsyncRedisCluster'):
        raise NotImplementedError('cluster_flushslots is not supported on the cluster client; use a raw node connection')
    return client.cluster_flushslots()

Type guard

from redis.cluster import RedisCluster
from redis.asyncio.cluster import RedisCluster as AsyncRedisCluster

def is_cluster_client(client) -> bool:
    return isinstance(client, (RedisCluster, AsyncRedisCluster))

Try / catch

try:
    client.cluster_flushslots()
except NotImplementedError:
    # fall back to raw node connection or skip
    pass

Prevention

When it happens

Trigger: Calling client.cluster_flushslots() on a RedisCluster or redis.asyncio.RedisCluster instance, with any arguments. The body raises unconditionally; no target_nodes value avoids it.

Common situations: Porting scripts that call CLUSTER FLUSHSLOTS against standalone node connections; attempting cluster cleanup programmatically during test teardown; auto-completing from IDE suggestions without checking the method is implemented.

Related errors


AI-assisted analysis of redis/redis-py@6a6b581b48 (2026-08-10). Data as JSON: /api/errors/f6924f074a23de83. Report an issue: GitHub.

Appendix: source

Thrown at redis/commands/cluster.py:1021

        self: AsyncClientProtocol, target_node: "TargetNodesT"
    ) -> Awaitable[ClusterLinksResponse]: ...

    def cluster_links(
        self, target_node: "TargetNodesT"
    ) -> ClusterLinksResponse | Awaitable[ClusterLinksResponse]:
        """
        Each node in a Redis Cluster maintains a pair of long-lived TCP link with each
        peer in the cluster: One for sending outbound messages towards the peer and one
        for receiving inbound messages from the peer.

        This command outputs information of all such peer links as an array.

        For more information see https://redis.io/commands/cluster-links
        """
        return self.execute_command("CLUSTER LINKS", target_nodes=target_node)

    def cluster_flushslots(self, target_nodes: "TargetNodesT" | None = None) -> None:
        raise NotImplementedError(
            "CLUSTER FLUSHSLOTS is intentionally not implemented in the client."
        )

    def cluster_bumpepoch(self, target_nodes: "TargetNodesT" | None = None) -> None:
        raise NotImplementedError(
            "CLUSTER BUMPEPOCH is intentionally not implemented in the client."
        )

    def readonly(self, target_nodes: "TargetNodesT" | None = None) -> ResponseT:
        """
        Enables read queries.
        The command will be sent to the default cluster node if target_nodes is
        not specified.

        For more information see https://redis.io/commands/readonly
        """
        if target_nodes == "replicas" or target_nodes == "all":
            # read_from_replicas will only be enabled if the READONLY command

View on GitHub (pinned to 6a6b581b48)