redis/go-redis · error

redis: got %d elements in the map, wanted %d

Error message

redis: got %d elements in the map, wanted %d

What it means

ReadFixedMapLen asserts the reply map has an exact expected number of key-value pairs. The server returned a map (or RESP2 array-as-map) with a different count, breaking the fixed-shape contract used e.g. by readRunningScript, readEngines (FUNCTION/SCRIPT replies). It protects positional key-value decoding from silent misalignment.

Source

Thrown at internal/proto/reader.go:742

	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.
// 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.

View on GitHub (pinned to c5cad058c7)

Solutions

  1. Match the server/RedisGears version to what the parser expects, or upgrade go-redis for new reply shapes
  2. Use ReadMapLen and iterate keys dynamically when the field set can vary
  3. Compare actual reply via redis-cli --raw against the expected fixed length
  4. Avoid mixing Redis versions behind one endpoint during rolling upgrades

Example fix

// before
err := reader.ReadFixedMapLen(3)
// after: accept variable engine field counts
n, err := reader.ReadMapLen()
if err != nil { return err }
for i := 0; i < n; i++ { /* read key/value pairs */ }
Defensive patterns

Strategy: validation

Validate before calling

// confirm expected field count from server before fixed-map parse
// redis-cli --raw "FUNCTION LIST" to count key/value pairs on your version

Try / catch

err := reader.ReadFixedMapLen(3)
if err != nil && strings.Contains(err.Error(), "wanted") {
  return fmt.Errorf("function/engine reply shape mismatch (server version?): %w", err)
}

Prevention

When it happens

Trigger: Calling ReadFixedMapLen(n) for FUNCTION LIST / SCRIPT related replies when the server returns a different pair count — typically a Redis version difference in FUNCTION/FCALL metadata, or a module (RedisGears engines) reporting a different field set.

Common situations: Server upgraded/downgraded between Redis versions with changed reply fields; modules installed or removed changing engine listings; custom proxies altering reply contents.

Related errors


AI-assisted analysis of redis/go-redis@c5cad058c7 (2026-09-01). Data as JSON: /api/errors/4b3e294409e3b1c9. Report an issue: GitHub.