redis/redis-py · error · RedisClusterException

shard_hint is deprecated in cluster mode

Error message

shard_hint is deprecated in cluster mode

What it means

Raised by RedisCluster.pipeline() when shard_hint is passed as a truthy value. shard_hint is a connection-pool concept from the standalone Redis client used to route connections to a specific shard; it has no meaning in cluster mode where routing is automatic by hash slot. The cluster pipeline explicitly rejects it to prevent silent misconfiguration.

Source

Thrown at redis/asyncio/cluster.py:1456

            command_name=command,
            duration_seconds=time.monotonic() - start_time,
            connection=target_node,
            error=e,
        )
        raise e

    def pipeline(
        self, transaction: Optional[Any] = None, shard_hint: Optional[Any] = None
    ) -> "ClusterPipeline":
        """
        Create & return a new :class:`~.ClusterPipeline` object.

        Cluster implementation of pipeline does not support transaction or shard_hint.

        :raises RedisClusterException: if transaction or shard_hint are truthy values
        """
        if shard_hint:
            raise RedisClusterException("shard_hint is deprecated in cluster mode")

        return ClusterPipeline(self, transaction)

    def pubsub(
        self,
        node: Optional["ClusterNode"] = None,
        host: Optional[str] = None,
        port: Optional[int] = None,
        **kwargs: Any,
    ) -> "ClusterPubSub":
        """
        Create and return a ClusterPubSub instance.

        Allows passing a ClusterNode, or host&port, to get a pubsub instance
        connected to the specified node

        :param node: ClusterNode to connect to
        :param host: Host of the node to connect to

View on GitHub (pinned to da03cdc7e8)

Solutions

  1. Drop the shard_hint argument entirely: rc.pipeline().
  2. If you need to target a specific shard, instead pass target_nodes on the individual pipeline commands or use the per-node connection pool directly.
  3. Set shard_hint=None (the default) explicitly to make the intent clear during migration.

Example fix

// before
pipe = rc.pipeline(transaction=True, shard_hint='users')

// after
pipe = rc.pipeline(transaction=True)
Defensive patterns

Strategy: validation

Validate before calling

def cluster_pipeline(rc, transaction=None, shard_hint=None):
    if shard_hint:
        raise ValueError('shard_hint is not supported by RedisCluster.pipeline()')
    return rc.pipeline(transaction=transaction)

Type guard

from typing import Any

def is_clean_pipeline_kwargs(transaction=None, shard_hint=None) -> bool:
    return not shard_hint

Try / catch

try:
    pipe = rc.pipeline(transaction=True, shard_hint=hint)
except Exception as e:
    if 'shard_hint' in str(e):
        pipe = rc.pipeline(transaction=True)
    else:
        raise

Prevention

When it happens

Trigger: Calling rc.pipeline(transaction=True, shard_hint='somehint') or porting standalone code rc.pipeline(shard_hint=...) to a RedisCluster client. Any truthy (non-None, non-empty) value triggers it at cluster.py:1455.

Common situations: Copy-pasting pipeline() kwargs from a standalone Redis() client into a RedisCluster() client; legacy codebases that used shard_hint with redis-py's old cluster sharding helpers.

Related errors


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