redis/redis · error

[ERR] Invalid arguments: you need to pass either a valid add

Error message

[ERR] Invalid arguments: you need to pass either a valid address (ie. 120.0.0.1:7000) or space separated IP and port (ie. 120.0.0.1 7000)

What it means

Printed via the CLUSTER_MANAGER_INVALID_HOST_ARG macro (src/redis-cli.c:7769) from clusterManagerCommandAddNode's `invalid_args` label when getClusterHostFromCmdArgs fails for either the new-node argument (argv[0]) or the reference-cluster argument (argv[1..]). The command needs exactly two host specs and could not extract an ip:port from one of them.

Source

Thrown at src/redis-cli.c:7769

        sleep(1);
        clusterManagerWaitForClusterJoin();
        clusterManagerLogInfo(">>> Configure node as replica of %s:%d.\n",
                              master_node->ip, master_node->port);
        freeReplyObject(reply);
        reply = CLUSTER_MANAGER_COMMAND(new_node, "CLUSTER REPLICATE %s",
                                        master_node->name);
        if (!(success = clusterManagerCheckRedisReply(new_node, reply, NULL)))
            goto cleanup;
    }
    clusterManagerLogOk("[OK] New node added correctly.\n");
cleanup:
    if (!added && new_node) freeClusterManagerNode(new_node);
    if (reply) freeReplyObject(reply);
    if (function_restore_reply) freeReplyObject(function_restore_reply);
    if (function_list_reply) freeReplyObject(function_list_reply);
    return success;
invalid_args:
    fprintf(stderr, CLUSTER_MANAGER_INVALID_HOST_ARG);
    return 0;
}

static int clusterManagerCommandDeleteNode(int argc, char **argv) {
    UNUSED(argc);
    int success = 1;
    int port = 0;
    char *ip = NULL;
    if (!getClusterHostFromCmdArgs(1, argv, &ip, &port)) goto invalid_args;
    char *node_id = argv[1];
    clusterManagerLogInfo(">>> Removing node %s from cluster %s:%d\n",
                          node_id, ip, port);
    clusterManagerNode *ref_node = clusterManagerNewNode(ip, port, 0);
    clusterManagerNode *node = NULL;

    // Load cluster information
    if (!clusterManagerLoadInfoFromNode(ref_node)) return 0;

View on GitHub (pinned to 3acc0c49cf)

Solutions

  1. Provide both targets in `ip:port` form: `redis-cli --cluster add-node <newip>:<newport> <existingip>:<existingport>`.
  2. Verify argument count is exactly two host specs (flags like --cluster-slave aside).
  3. Ensure ports are non-zero numeric; avoid bare hostnames without a `:port`.
  4. Echo the command first to catch empty `$NEWPORT` / `$REFPORT` shell expansions.

Example fix

// before
redis-cli --cluster add-node 10.0.0.9 10.0.0.1
// after
redis-cli --cluster add-node 10.0.0.9:7000 10.0.0.1:7000
Defensive patterns

Strategy: validation

Validate before calling

// Validate the CLUSTER-related CLI argv (address OR space-separated ip+port) before dispatch.
function validateClusterArgs(argv) {
  const args = Array.isArray(argv) ? argv : String(argv).trim().split(/\s+/);
  if (args.length === 1) {
    return validateAddressFormat(args[0]); // reuse [123] validator
  }
  if (args.length === 2) {
    const [host, portStr] = args;
    if (!host || !/^(\[[^\]]+\]|[A-Za-z0-9.:-]+)$/.test(host)) {
      throw new Error('Invalid arguments: pass host:port OR host port');
    }
    const port = Number(portStr);
    if (!Number.isInteger(port) || port < 1 || port > 65535) {
      throw new Error('Invalid arguments: port out of range');
    }
    return { host: host.replace(/^\[|\]$/g, ''), port };
  }
  throw new Error('Invalid arguments: pass a valid address (host:port) or space-separated host port');
}

Type guard

function isClusterArgvShape(v) {
  if (!Array.isArray(v)) return false;
  if (v.length < 1 || v.length > 2) return false;
  return v.every(x => typeof x === 'string' && x.trim().length > 0);
}

Try / catch

try {
  target = validateClusterArgs(process.argv.slice(idx));
} catch (e) {
  if (/Invalid arguments/i.test(String(e.message))) {
    console.error('Usage: <host:port | host port>');
    process.exit(2);
  }
  throw e;
}

Prevention

When it happens

Trigger: Invoke `--cluster add-node` with the wrong shape: only one argument, missing `:port`, an empty port token, or non-numeric port so atoi yields 0 (getClusterHostFromCmdArgs rejects !port). Both the new node and the existing cluster reference must parse.

Common situations: Forgetting the second (reference cluster) argument; passing `add-node host1 host2` instead of `host1:port host2:port`; copy-paste leaving the port off one side; shell variable that expanded to an empty string for the port token.

Related errors


AI-assisted analysis of redis/redis@3acc0c49cf (2026-08-01). Data as JSON: /data/errors/e59c1aa1f589eafd.json. Report an issue: GitHub.