redis/node-redis · error · Error
Could not find shard
Error message
Could not find shard
What it means
Thrown inside #handleSmigrated (cluster-slots.ts:422) during Enterprise SMIGRATED slot-migration handling. When a destination node already exists in nodeByAddress but its host:port does not correspond to any Shard in this.slots, the migration code cannot determine which shard owns the destination and throws. This is an internal topology invariant violation, not a normal operational error.
Source
Thrown at packages/client/lib/cluster/cluster-slots.ts:422
const promises: Promise<unknown>[] = [];
destMasterNode = this.#initiateSlotNode({ host: host, port: port, id: `smigrated-${host}:${port}` }, false, true, new Set(), promises);
await Promise.all([...promises, this.#initiateShardedPubSubClient(destMasterNode)]);
// Pause new destination until migration is complete
destMasterNode.client?._pause();
destMasterNode.pubSub?.client._pause();
// In case destination node didnt exist, this means Shard didnt exist as well, so creating a new Shard is completely fine
destShard = {
master: destMasterNode
};
} else {
// DEBUG: Log all master hosts/ports in slots array to diagnose mismatch
const allMasters = [...new Set(this.slots)].map(s => `${s.master.host}:${s.master.port}`);
dbgMaintenance(`[CSlots]: Searching for shard with host=${host}, port=${port}. Available masters in slots: ${allMasters.join(', ')}`);
// In case destination node existed, this means there was a Shard already, so its best if we can find it.
const existingShard = this.slots.find(shard => shard.master.host === host && shard.master.port === port);
if (!existingShard) {
dbgMaintenance("Could not find shard");
throw new Error('Could not find shard');
}
destShard = existingShard;
// Pause existing destination during command transfer
destMasterNode.client?._pause();
destMasterNode.pubSub?.client._pause();
}
// Track last destination for slotless commands later
lastDestNode = destMasterNode;
// 3. Convert slots to Set and update shard mappings
const destinationSlots = new Set<number>();
for (const slot of slots) {
if (typeof slot === 'number') {
this.slots[slot] = destShard;
destinationSlots.add(slot);
allMovingSlots.add(slot);
} else {View on GitHub (pinned to bb5beb5657)
Solutions
- Let the next background topology refresh resync this.slots; the error is emitted on 'error' and the migration entry is skipped, so the cluster can self-heal.
- Attach a cluster.on('error', ...) handler to observe and log these without crashing.
- If recurring, trigger an explicit topology refresh and report the SMIGRATED sequence + addresses to maintainers — it indicates a client/server topology disagreement.
Example fix
// no user API triggers this directly; handle defensively:
cluster.on('error', (err) => {
if (err.message === 'Could not find shard') {
logger.warn('SMIGRATED topology mismatch, will resync on next refresh', err);
return; // do not crash
}
throw err;
}); Defensive patterns
Strategy: try-catch
Type guard
function isShardNotFound(e: unknown): boolean {
return e instanceof Error && /Could not find shard/i.test(e.message);
} Try / catch
cluster.on('error', (e) => {
if (isShardNotFound(e)) { logger.warn('topology mismatch during SMIGRATED; will resync', e); return; }
throw e;
}); Prevention
- Always attach a cluster.on('error') handler — this surfaces there.
- Let background topology refresh self-heal rather than crashing.
- Recurring occurrences warrant a maintainer report with seqId/addresses.
When it happens
Trigger: An Enterprise Redis cluster emits an SMIGRATED event whose destination address exists as a node but is not represented as a Shard in the slots array — typically a topology that is out of sync with the migration event (e.g. concurrent topology refresh, stale SMIGRATED seqId, or a race between discovery and migration).
Common situations: Active slot migrations under Enterprise maintenance while a topology refresh races; duplicate/delayed SMIGRATED events; version mismatch between client topology assumptions and server migration state.
Related errors
- Unknown request policy ${requestPolicy}
- Unknown response policy ${responsePolicy}
- Request policy ${requestPolicy} produced no target nodes
- Cannot find node ${address}
- FT.CURSOR: the node serving cursor ${token} on index "${argT
AI-assisted analysis of redis/node-redis@bb5beb5657 (2026-08-03).
Data as JSON: /data/errors/7bb34c8116902ac3.json.
Report an issue: GitHub.