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

  1. Re-fetch connections immediately before sending: await proxyController.getConnections()
  2. Ensure the cluster client stays connected during the migration (increase socket timeouts)
  3. 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

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


AI-assisted analysis of redis/node-redis@90fd0652bc (2026-08-11). Data as JSON: /api/errors/6825038bab0acf95. Report an issue: GitHub.