redis/node-redis · error · Error
[Proxy] Failed to send SMIGRATING notification: ${migratingR
Error message
[Proxy] Failed to send SMIGRATING notification: ${migratingResult.error} What it means
In triggerMigrate, after building the SMIGRATING push notification, the proxy controller attempts to send it to the source node's first client connection. If sendToClient returns success === false, this error throws with the controller's error detail. It means the proxy could not deliver the RESP push to the live client connection.
Source
Thrown at packages/test-utils/lib/fault-injector/proxied-fault-injector-cluster.ts:107
? nodes.length - 1
: nodes.length;
const shouldMigrateHalfSlots = params.slot_migration === "half";
const slots = shouldMigrateHalfSlots
? `0-${Math.floor(TOTAL_SLOTS / visibleNodesCount / 2) - 1}`
: `0-${Math.floor(TOTAL_SLOTS / visibleNodesCount) - 1}`;
const sMigratingNotification = buildSMigratingNotification(slots);
const sourceNode = nodes[0];
const migratingResult = await this.proxyController.sendToClient(
connections[sourceNode.id][0],
sMigratingNotification
);
if (!migratingResult.success) {
throw new Error(
`[Proxy] Failed to send SMIGRATING notification: ${migratingResult.error}`
);
}
// 2. Simulate maintenance delay
await setTimeout(2_000);
const isNewDestination = params.destination_type === "new";
if (isNewDestination && !nodeWithoutConnections) {
throw new Error(`[Proxy] No node with no connections`);
}
const destinationNode = isNewDestination
? nodeWithoutConnections!
: nodes.at(-1)!; // Get the last node as the destination
if (!destinationNode) {View on GitHub (pinned to 90fd0652bc)
Solutions
- Re-fetch connections immediately before sending: await proxyController.getConnections()
- Ensure the cluster client stays connected during the migration (increase socket timeouts)
- Inspect migratingResult.error in the message for the controller's specific refusal reason
Example fix
// before — stale connection id const conn = connections[sourceNode.id][0]; const r = await this.proxyController.sendToClient(conn, msg); // after — refresh connections right before send const fresh = await this.proxyController.getConnections(); const conn = fresh[sourceNode.id][0]; const r = await this.proxyController.sendToClient(conn, msg);
Defensive patterns
Strategy: retry
Validate before calling
async function sendWithFreshConnection(proxyController: ProxyController, nodeId: string, msg: string) {
const fresh = await proxyController.getConnections();
const conn = fresh[nodeId]?.[0];
if (!conn) throw new Error(`No live connection for node ${nodeId}`);
return proxyController.sendToClient(conn, msg);
} Type guard
function isSendSuccess(r: { success: boolean; error?: string }): r is { success: true } {
return r.success === true;
} Try / catch
try {
const r = await proxyController.sendToClient(conn, msg);
if (!r.success) throw new Error(`[Proxy] Failed: ${r.error}`);
} catch (e) {
if (e instanceof Error && /Failed to send SMIGRATING/.test(e.message)) {
}
throw e;
} Prevention
- Re-fetch connections immediately before sendToClient to avoid stale ids
- Keep the cluster client connected during migrations (raise socket timeouts)
- Inspect migratingResult.error to distinguish connection-closed from proxy-internal failures
When it happens
Trigger: The target client connection (connections[sourceNode.id][0]) was closed/reset between getConnections and sendToClient; the proxy controller's send buffer rejected the write; the connection id is stale.
Common situations: The Redis client disconnected mid-migration (timeout, network blip); the cluster client reconnected and connection ids changed; proxy controller in an inconsistent state after a prior failed action.
Related errors
- [Proxy] No node with no connections
- [Proxy] No destination node
- [Proxy] Failed to send SMIGRATED notification: ${migratedRes
- No slots to migrate
- Action ${action.type} not implemented
AI-assisted analysis of redis/node-redis@90fd0652bc (2026-08-11).
Data as JSON: /api/errors/6825038bab0acf95.
Report an issue: GitHub.