redis/go-redis · error
redis: the length of the array must be a multiple of 2, got:
Error message
redis: the length of the array must be a multiple of 2, got: %d
What it means
When reading a map reply, the parser sometimes receives an RESP2 array (some commands and RESP2 encode maps as flat arrays). It then requires the array length to be even — each key needs a value. An odd length means the flat key/value stream is malformed, so decoding would misalign.
Source
Thrown at internal/proto/reader.go:766
// If responding to the array type (RespArray/RespSet/RespPush),
// it must be a multiple of 2 and return n/2.
// Other types will return an error.
func (r *Reader) ReadMapLen() (int, error) {
line, err := r.ReadLine()
if err != nil {
return 0, err
}
switch line[0] {
case RespMap:
return replyLen(line)
case RespArray, RespSet, RespPush:
// Some commands and RESP2 protocol may respond to array types.
n, err := replyLen(line)
if err != nil {
return 0, err
}
if n%2 != 0 {
return 0, fmt.Errorf("redis: the length of the array must be a multiple of 2, got: %d", n)
}
return n / 2, nil
default:
return 0, fmt.Errorf("redis: can't parse map reply: %.100q", line)
}
}
// DiscardNext read and discard the data represented by the next line.
func (r *Reader) DiscardNext() error {
line, err := r.readLine()
if err != nil {
return err
}
return r.Discard(line)
}
// Discard the data represented by line.
func (r *Reader) Discard(line []byte) (err error) {View on GitHub (pinned to c5cad058c7)
Solutions
- Reset the connection after any read timeout/partial read instead of reusing it — desync is the usual cause
- Verify no proxy/load balancer truncates or rewrites multi-element replies
- Check the command's reply shape against the server version (some commands changed arity between versions)
- Re-run the failing command with redis-cli --raw and count the flat elements
Defensive patterns
Strategy: validation
Validate before calling
// odd flat-array length indicates desync — validate alignment upstream // ensure prior replies consumed: err := cmd.Err(); consume full pipeline
Try / catch
n, err := reader.ReadMapLen()
if err != nil && strings.Contains(err.Error(), "multiple of 2") {
logger.Error("map stream misaligned; dropping connection", "err", err)
_ = conn.Close()
return err
} Prevention
- Never reuse a pooled conn after timeout/partial read
- Ensure pipelines are fully flushed and read
- Check middleware for reply rewriting
- Count flat elements with redis-cli --raw when diagnosing
When it happens
Trigger: ReadMapLen called (by readReply, stringInterfaceMapParser, readStreamGroups, readXInfoStreamConsumers, readFunctions, readEngines) when the reply arrives as an RESP2 array with an odd element count — a malformed or desynchronized stream, or a server/proxy producing a broken flat map encoding.
Common situations: Protocol desync after an earlier reply was partially read; buggy middleware rewriting HGETALL/XINFO-style replies; truncated reply from an aborted connection being reused.
Related errors
- redis: got %d elements in the map, wanted %d
- redis: can't parse map reply: %.100q
- redis: can't parse reply=%.100q reading string into buffer
- redis: can't parse reply=%.100q reading string
- redis: got %d elements in the array, wanted %d
AI-assisted analysis of redis/go-redis@c5cad058c7 (2026-09-01).
Data as JSON: /api/errors/e0eea2baf2409a1f.
Report an issue: GitHub.