go-redis/redis · error

redis: got %d elements in the key-value array, wanted a mult

Error message

redis: got %d elements in the key-value array, wanted a multiple of 2

What it means

Returned by KeyValueSliceCmd.readReply (command.go:2256, used by HRandFieldWithValues) when the reply is a flat RESP2 array whose element count is odd. KeyValueSliceCmd accepts either a RESP3 array-of-pairs or a RESP2 flat [k,v,k,v,...] array; a flat array with an odd length cannot be split into key/value pairs and is reported rather than silently mis-parsing.

Source

Thrown at command.go:2256

	}

	// If the n is 0, can't continue reading.
	if n == 0 {
		cmd.val = make([]KeyValue, 0)
		return nil
	}

	typ, err := rd.PeekReplyType()
	if err != nil {
		return err
	}
	array := typ == proto.RespArray

	if array {
		cmd.val = make([]KeyValue, n)
	} else {
		if n%2 != 0 {
			return fmt.Errorf("redis: got %d elements in the key-value array, wanted a multiple of 2", n)
		}
		cmd.val = make([]KeyValue, 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].Key, err = rd.ReadString(); err != nil {
			return err
		}

		if cmd.val[i].Value, err = rd.ReadString(); err != nil {
			return err
		}

View on GitHub (pinned to 36d97525cd)

Solutions

  1. Switch the client to RESP3 (Options.Protocol = 3) so the reply comes as a proper array-of-pairs.
  2. Upgrade Redis to a version known to return the documented HRANDFIELD WITHVALUES shape.
  3. If the error persists, capture a RESP trace (e.g. via redis-cli MONITOR or a tcpdump) and file a bug — odd counts indicate corruption or a server bug.

Example fix

// before
opts := redis.Options{Addr: addr /* RESP2 default */}
rdb := redis.NewClient(&opts)
res, err := rdb.HRandFieldWithValues(ctx, "h", 5).Result() // odd-length → error

// after
opts := redis.Options{Addr: addr, Protocol: 3}
rdb := redis.NewClient(&opts)
res, err := rdb.HRandFieldWithValues(ctx, "h", 5).Result()
Defensive patterns

Strategy: try-catch

Validate before calling

// Prefer RESP3 so HRANDFIELD WITHVALUES arrives as array-of-pairs.
opts := redis.Options{Addr: addr, Protocol: 3}

Try / catch

res, err := rdb.HRandFieldWithValues(ctx, "h", 5).Result()
if err != nil && strings.Contains(err.Error(), "wanted a multiple of 2") {
    // odd-length RESP2 array — switch to RESP3 or capture a RESP trace
}

Prevention

When it happens

Trigger: Calling HRandFieldWithValues with the client using RESP2 (Protocol <= 2) and the server returning a malformed/odd-length array; or a Redis version/build where HRANDFIELD WITHVALUES produced an unexpected shape.

Common situations: Running against an old or patched Redis build that returns odd counts; a man-in-the-middle or proxy corrupting the byte stream; a future Redis change to HRANDFIELD reply shape.

Related errors


AI-assisted analysis of go-redis/redis@36d97525cd (2026-08-06). Data as JSON: /data/errors/0a9f2eaad7f3432d.json. Report an issue: GitHub.