Redis Cluster returns `CROSSSLOT Keys in request don't hash to the same slot` when you attempt a multi-key operation (like MGET, MSET, or sharded Pub/Sub) on keys that hash to different hash slots. Redis Cluster partitions data across 16384 slots, and multi-key commands require all keys to map to the same slot unless you use hash tags. This guide explains slot hashing, hash tags, and how to structure keys or use client-side routing to avoid cross-slot errors.
Redis Cluster divides the key space into 16384 hash slots, each assigned to a specific master node. When you issue a command that involves multiple keys—such as `MGET`, `MSET`, or sharded Pub/Sub operations—Redis must ensure all those keys belong to the same hash slot; otherwise, the operation cannot be performed atomically on a single node. The error "CROSSSLOT Keys in request don't hash to the same slot (sharded pubsub)" appears when the client library or Redis itself detects that the keys involved in a multi‑key command hash to different slots. For sharded Pub/Sub, this means the subscription channels you're trying to publish to or subscribe from are spread across multiple cluster nodes, which Redis Cluster's sharded Pub/Sub does not support without explicit routing. To work around this limitation, you can either: 1. Use **hash tags** (curly braces `{}` inside the key name) to force keys to the same slot, 2. Restructure your data so that related keys naturally hash together, 3. Use client‑side routing to send each key to its correct node individually, or 4. Avoid multi‑key commands altogether in favor of single‑key operations.
Use redis-cli to check which slot each key belongs to:
# Connect to any Redis Cluster node
redis-cli -c -h <host> -p <port>
# Check slot for individual keys
CLUSTER KEYSLOT user:123:profile
CLUSTER KEYSLOT user:123:sessions
CLUSTER KEYSLOT session:456:data
# Or use the CRC16 algorithm directly
echo -n 'user:123:profile' | redis-cli --cluster call <host>:<port> CRC16 16384If the slot numbers differ, those keys cannot be used together in a multi‑key command unless you employ hash tags.
Redis allows you to wrap a portion of the key in curly braces {}; only the text inside the braces is used for slot calculation:
# Without hash tags – different slots
CLUSTER KEYSLOT user:123:profile # slot 7592
CLUSTER KEYSLOT user:123:sessions # slot 10411
# With hash tags – same slot
CLUSTER KEYSLOT user:{123}:profile # slot 3300 (based on '123')
CLUSTER KEYSLOT user:{123}:sessions # slot 3300 (based on '123')Update your application to use hash tags for related keys:
// Instead of
const keys = ['user:123:profile', 'user:123:sessions'];
// Use hash tags
const keys = ['user:{123}:profile', 'user:{123}:sessions'];Now MGET, MSET, and other multi‑key commands will work because both keys hash to slot 3300.
If hash tags are not feasible, break multi‑key commands into single‑key operations routed to the correct node:
// Instead of MGET that fails with CROSSSLOT
redis.mget('key1', 'key2', 'key3');
// Use individual GET calls with cluster‑aware client
const client = new Redis.Cluster([...]);
const values = await Promise.all([
client.get('key1'),
client.get('key2'),
client.get('key3')
]);For deletions:
# Instead of DEL key1 key2 key3
DEL key1
DEL key2
DEL key3Most Redis Cluster clients (ioredis, redis-py-cluster) handle this routing automatically when you use single‑key commands.
Redis Cluster's sharded Pub/Sub requires all channels in a single command to hash to the same slot. Use hash tags or client‑side routing:
# Without hash tags – may fail
PSUBSCRIBE news:* notifications:*
# With hash tags – channels hash to same slot
PSUBSCRIBE news:{sports}:* notifications:{sports}:*Alternatively, subscribe to each channel separately:
// Cluster-aware Pub/Sub client
const sub = redis.duplicate();
await sub.subscribe('channel1', 'channel2', 'channel3');
// Client library routes each subscription to correct nodeRemember that non‑sharded Pub/Sub (regular PUBLISH/SUBSCRIBE) broadcasts to all nodes, so it doesn't have cross‑slot restrictions but also doesn't scale horizontally.
Modern Redis clients automatically handle slot routing and hash‑tag extraction. Verify your client's cluster support:
// ioredis example
const Redis = require('ioredis');
const cluster = new Redis.Cluster([
{ host: '127.0.0.1', port: 7000 },
{ host: '127.0.0.1', port: 7001 },
]);
// The client will automatically route multi‑key commands
// or throw clear errors if cross‑slot is unavoidable# redis-py-cluster example
from rediscluster import RedisCluster
startup_nodes = [
{'host': '127.0.0.1', 'port': 7000},
{'host': '127.0.0.1', port: 7001},
]
rc = RedisCluster(startup_nodes=startup_nodes, decode_responses=True)These clients maintain a slot‑to‑node map and can split cross‑slot MGET/MSET into parallel requests when possible.
Redis Cluster's slot‑hashing algorithm is CRC16 modulo 16384. The same algorithm is used for both data keys and Pub/Sub channel names in sharded mode. Hash tags work by extracting the substring between the first { and the next } (or end of string) and hashing only that substring.
Performance considerations: Splitting a 100‑key MGET into 100 individual GET requests increases network round‑trips. If you cannot use hash tags, consider batching keys by slot on the client side and issuing separate multi‑key commands per slot.
Migration strategy: When moving from standalone Redis to Redis Cluster, audit all multi‑key commands and Pub/Sub usage. Tools like redis‑cli --cluster check can identify cross‑slot violations before going live.
Sharded vs regular Pub/Sub: Sharded Pub/Sub (SSUBSCRIBE/SPUBLISH) scales better for high‑volume topics because messages are routed to a single node per channel. Regular Pub/Sub broadcasts to all nodes, which can become a bottleneck. Choose based on your use case.
ERR Unbalanced XREAD list of streams
How to fix "ERR Unbalanced XREAD list" in Redis
ERR syntax error
How to fix "ERR syntax error" in Redis
ConnectionError: Error while reading from socket
ConnectionError: Error while reading from socket in redis-py
ERR unknown command
How to fix ERR unknown command in Redis
Command timed out
How to fix 'Command timed out' in ioredis