go-redis/redis · error
redis: multi-shard command %s has no key arguments
Error message
redis: multi-shard command %s has no key arguments
What it means
Returned by executeMultiShard when a command classified as multi-shard (ReqMultiShard) has no key arguments at the expected position. The router derives firstKeyPos from command metadata; if it is 0 or beyond the argument list, the command cannot be split across shards and is rejected.
Source
Thrown at osscluster_router.go:122
if len(state.Masters) == 0 {
return errClusterNoNodes
}
return c.executeParallel(ctx, cmd, state.Masters, policy)
}
// executeMultiShard handles commands that operate on multiple keys across shards
func (c *ClusterClient) executeMultiShard(ctx context.Context, cmd Cmder, policy *routing.CommandPolicy) error {
args := cmd.Args()
firstKeyPos := cmdFirstKeyPosWithInfo(cmd, c.cmdInfoPeek(cmd.Name()))
stepCount := int(cmd.stepCount())
if stepCount == 0 {
stepCount = 1 // Default to 1 if not set
}
if firstKeyPos == 0 || firstKeyPos >= len(args) {
return fmt.Errorf("redis: multi-shard command %s has no key arguments", cmd.Name())
}
// Group keys by slot
slotMap := make(map[int][]string)
keyOrder := make([]string, 0)
for i := firstKeyPos; i < len(args); i += stepCount {
key, ok := args[i].(string)
if !ok {
return fmt.Errorf("redis: non-string key at position %d: %v", i, args[i])
}
slot := hashtag.Slot(key)
slotMap[slot] = append(slotMap[slot], key)
for j := 1; j < stepCount; j++ {
if i+j >= len(args) {
break
}View on GitHub (pinned to 36d97525cd)
Solutions
- Ensure the command is called with at least one key argument at the expected position.
- For dynamic builders, guard against an empty key slice before issuing the command.
- If using a module command, verify its key spec / command policy is registered correctly.
Example fix
// before client.Do(ctx, "MSET") // after client.Do(ctx, "MSET", "k1", "v1", "k2", "v2")
Defensive patterns
Strategy: validation
Validate before calling
func hasKeyArgs(cmd redis.Cmder) bool {
args := cmd.Args()
return len(args) >= 2 // command name + at least one key
} Try / catch
if err := cmd.Err(); err != nil && strings.Contains(err.Error(), "has no key arguments") {
// ensure the argument list contains at least one key before re-issuing
} Prevention
- Guard dynamic argument builders against empty key slices.
- Validate that multi-key commands receive at least one key.
- For module commands, register the correct key spec / command policy.
When it happens
Trigger: Calling a multi-key command (e.g. MSET, DEL with multiple keys, or a module command with multi-shard policy) with zero keys, or with arguments where the key position does not line up with the command's declared key spec. Also if a custom Cmder reports the wrong step/first-key metadata.
Common situations: Dynamically building an argument list that ends up empty, a wrapper that drops key arguments, or a command-policy/key-spec mismatch for a module command.
Related errors
- redis: no valid results to aggregate for max operation
- redis: no valid results to aggregate for logical AND operati
- redis: no valid results to aggregate for logical OR operatio
- redis: cluster has no nodes
- routing: unknown response_policy %q
AI-assisted analysis of go-redis/redis@36d97525cd (2026-08-06).
Data as JSON: /data/errors/25a278165b16da5f.json.
Report an issue: GitHub.