go-redis/redis · error
redis: got %d elements in the sorted set array, wanted a mul
Error message
redis: got %d elements in the sorted set array, wanted a multiple of 2
What it means
Returned by ZSliceCmd.readReply (command.go:4423, used by ZRangeWithScores, ZPopMin/Max, ZInterWithScores, ZUnionWithScores, ZRangeByScoreWithScores, ZRandMemberWithScores, ZDiffWithScores). The reply is either a RESP3 array-of-pairs or a RESP2 flat [member,score,member,score,...] array; a flat RESP2 array with an odd element count cannot be split into member/score pairs and is reported rather than silently mis-parsing.
Source
Thrown at command.go:4423
}
// If the n is 0, can't continue reading.
if n == 0 {
cmd.val = make([]Z, 0)
return nil
}
typ, err := rd.PeekReplyType()
if err != nil {
return err
}
array := typ == proto.RespArray
if array {
cmd.val = make([]Z, n)
} else {
if n%2 != 0 {
return fmt.Errorf("redis: got %d elements in the sorted set array, wanted a multiple of 2", n)
}
cmd.val = make([]Z, n/2)
}
for i := 0; i < len(cmd.val); i++ {
if array {
if err = rd.ReadFixedArrayLen(2); err != nil {
return err
}
}
if cmd.val[i].Member, err = rd.ReadString(); err != nil {
return err
}
if cmd.val[i].Score, err = rd.ReadFloat(); err != nil {
return err
}View on GitHub (pinned to 36d97525cd)
Solutions
- Switch the client to RESP3 (Options.Protocol = 3) so the reply arrives as a proper array-of-pairs.
- Remove or bypass any proxy that may be rewriting RESP frames, and connect directly to Redis.
- Capture a RESP trace (tcpdump/redis-cli) to confirm whether Redis or an intermediary is producing the odd length; file a bug against the offender.
Example fix
// before
opts := redis.Options{Addr: addr /* RESP2 */}
rdb := redis.NewClient(&opts)
members, err := rdb.ZRangeWithScores(ctx, "s", 0, -1).Result() // odd length → error
// after
opts := redis.Options{Addr: addr, Protocol: 3}
rdb := redis.NewClient(&opts)
members, err := rdb.ZRangeWithScores(ctx, "s", 0, -1).Result() Defensive patterns
Strategy: try-catch
Validate before calling
// Prefer RESP3 so sorted-set *WithScores commands arrive as array-of-pairs.
opts := redis.Options{Addr: addr, Protocol: 3} Try / catch
members, err := rdb.ZRangeWithScores(ctx, "s", 0, -1).Result()
if err != nil && strings.Contains(err.Error(), "sorted set array, wanted a multiple of 2") {
// odd-length RESP2 array — switch to RESP3 or bypass any proxy
} Prevention
- Use RESP3 for *WithScores sorted-set commands.
- Connect directly to Redis, bypassing RESP-mangling proxies.
- Capture a RESP trace to identify the source of odd-length arrays.
When it happens
Trigger: Calling a *WithScores sorted-set command with the client on RESP2 and the server returning an odd-length array — typically a sign of corruption, a proxy rewriting the frame, or a Redis build with a non-standard reply shape.
Common situations: A RESP-mangling proxy (twemproxy and friends) between client and Redis; an experimental/patched Redis; rare memory/link corruption. Legitimate Redis builds always return even-length flat arrays for these commands.
Related errors
- redis: got %d elements in the key-value array, wanted a mult
- redis: can't parse map-string-slice-interface reply: unexpec
- redis: got %d elements in the XMessage array, expected 2 or
- redis: got %d elements in XAutoClaim reply, wanted 2/3
- redis: got %d elements in XAutoClaimJustID reply, wanted 2/3
AI-assisted analysis of go-redis/redis@36d97525cd (2026-08-06).
Data as JSON: /data/errors/cd847a43dce092b0.json.
Report an issue: GitHub.