redis/go-redis · error
redis: can't parse array/set/push reply: %.100q
Error message
redis: can't parse array/set/push reply: %.100q
What it means
ReadArrayLen expected the next reply to be an array, set, or push type (RESP type bytes *, ~, >) but got something else. The parser cannot return a length for a non-aggregate reply, so it fails with the raw line for diagnosis. In RESP2 mode maps are also accepted via the array fallback, so this error means the reply is fundamentally not an aggregate.
Source
Thrown at internal/proto/reader.go:731
return err
}
if n != fixedLen {
return fmt.Errorf("redis: got %d elements in the array, wanted %d", n, fixedLen)
}
return nil
}
// ReadArrayLen Read and return the length of the array.
func (r *Reader) ReadArrayLen() (int, error) {
line, err := r.ReadLine()
if err != nil {
return 0, err
}
switch line[0] {
case RespArray, RespSet, RespPush:
return replyLen(line)
default:
return 0, fmt.Errorf("redis: can't parse array/set/push reply: %.100q", line)
}
}
// ReadFixedMapLen reads fixed map length.
func (r *Reader) ReadFixedMapLen(fixedLen int) error {
n, err := r.ReadMapLen()
if err != nil {
return err
}
if n != fixedLen {
return fmt.Errorf("redis: got %d elements in the map, wanted %d", n, fixedLen)
}
return nil
}
// ReadMapLen reads the length of the map type.
// If responding to the array type (RespArray/RespSet/RespPush),
// it must be a multiple of 2 and return n/2.View on GitHub (pinned to c5cad058c7)
Solutions
- Check the redis error actually returned (NOGROUP, WRONGTYPE, etc.) — handle command-level errors before parsing
- Set Protocol: 3 if server replies use RESP3 sets/pushes your parser expects as aggregates
- Verify each command's reply is fully consumed to avoid stream desync
- Run the command with redis-cli --raw to see the actual reply type
Example fix
// before: blindly parsing next reply as array
n, err := reader.ReadArrayLen()
// after: check cmd error first
if err := cmd.Err(); err != nil { return err }
n, err := reader.ReadArrayLen() Defensive patterns
Strategy: try-catch
Validate before calling
// ensure the key/command can return an aggregate // e.g. TYPE mykey == list/stream before XINFO/XRANGE-style reads
Type guard
func isArrayLikeReply(t byte) bool {
return t == '*' || t == '~' || t == '>' || t == '%'
} Try / catch
n, err := reader.ReadArrayLen()
if err != nil {
if strings.Contains(err.Error(), "can't parse array/set/push") {
// server returned an error or scalar; surface cmd error to caller
return cmd.Err()
}
return err
} Prevention
- Handle command errors (NOGROUP, WRONGTYPE) before parsing replies
- Match RESP2/RESP3 Protocol option to the server
- Consume replies fully to prevent desync
- Verify reply type with redis-cli --raw for new commands
When it happens
Trigger: readReply or stream/xinfo parsers (readXMessageSlice, readXMessage, readStreamGroups, readXInfoStream*) encountering a scalar, error, or nil reply where an array was expected — e.g. an error reply (like NOSCRIPT or NOGROUP) reaching the array parser due to desync, or a nil bulk reply.
Common situations: Calling XREADGROUP with an invalid group so the error surfaces mid-parse; RESP2/RESP3 protocol mismatch changing reply types; connection reuse after a partially consumed reply.
Related errors
- 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
- redis: can't parse map reply: %.100q
- redis: can't read raw reply: %.100q
AI-assisted analysis of redis/go-redis@c5cad058c7 (2026-09-01).
Data as JSON: /api/errors/cba44b0a4458bf1f.
Report an issue: GitHub.