go-redis/redis · error
redis: got %d elements in the XMessage array, expected 2 or
Error message
redis: got %d elements in the XMessage array, expected 2 or 4
What it means
Returned by readXMessage (command.go:2822), used by every stream-read path (XREAD/XREADGROUP/XCLAIM/XAUTOCLAIM). Each XMessage is encoded as an array whose length is either 2 (id + field-values) or 4 (id + field-values + claim metadata: millis-since-delivery + delivered-count, from XAUTOCLAIM/XCLAIM). Any other length yields this error rather than reading garbage fields.
Source
Thrown at command.go:2822
msgs := make([]XMessage, n)
for i := 0; i < len(msgs); i++ {
if msgs[i], err = readXMessage(rd); err != nil {
return nil, err
}
}
return msgs, nil
}
func readXMessage(rd *proto.Reader) (XMessage, error) {
// Read array length can be 2 or 4 (with CLAIM metadata)
n, err := rd.ReadArrayLen()
if err != nil {
return XMessage{}, err
}
if n != 2 && n != 4 {
return XMessage{}, fmt.Errorf("redis: got %d elements in the XMessage array, expected 2 or 4", n)
}
id, err := rd.ReadString()
if err != nil {
return XMessage{}, err
}
v, err := stringInterfaceMapParser(rd)
if err != nil {
if err != proto.Nil {
return XMessage{}, err
}
}
msg := XMessage{
ID: id,
Values: v,
}View on GitHub (pinned to 36d97525cd)
Solutions
- Pin client and server to compatible Redis versions (XCLAIM metadata shape is version-dependent).
- If on a fork/patched Redis, switch to upstream or implement a custom parser via Do().
- Capture a RESP trace to confirm whether the server or a proxy is producing the unexpected length, then file a bug against the offender.
Example fix
// before
msgs, err := rdb.XRead(ctx, &redis.XReadArgs{Streams: []string{"s", "0"}}).Result()
// err: got N elements in the XMessage array, expected 2 or 4
// after — pin a compatible server, or fall back to raw parsing
raw, err := rdb.Do(ctx, "XREAD", "STREAMS", "s", "0").Result()
// type-switch on raw and decode manually Defensive patterns
Strategy: try-catch
Try / catch
msgs, err := rdb.XRead(ctx, args).Result()
if err != nil && strings.Contains(err.Error(), "XMessage array, expected 2 or 4") {
// unexpected stream reply shape — pin client/server versions or decode raw
} Prevention
- Keep client and server Redis versions aligned across XCLAIM/XAUTOCLAIM changes.
- Avoid RESP-mangling proxies for stream workloads.
- On shape errors, capture a RESP trace before reporting.
When it happens
Trigger: Reading from a stream where the server returns an XMessage array with a length other than 2 or 4 — e.g. a future Redis adding more claim fields, a proxy rewriting the frame, or stream-data corruption.
Common situations: Upgrading the client but not the server (or vice-versa) across a version that changed XCLAIM/XAUTOCLAIM reply shape; a RESP proxy corrupting array framing; a Redis fork/fork-patched build with different stream reply semantics.
Related errors
- redis: got %d elements in XAutoClaim reply, wanted 2/3
- redis: got %d elements in XAutoClaimJustID reply, wanted 2/3
- 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 sorted set array, wanted a mul
AI-assisted analysis of go-redis/redis@36d97525cd (2026-08-06).
Data as JSON: /data/errors/1a3deac99ee33d8d.json.
Report an issue: GitHub.