redis/go-redis · error

redis: got %d elements in latency get, expected at least 4

Error message

redis: got %d elements in latency get, expected at least 4

What it means

This error comes from the reply parser for `LATENCY HISTORY`/`LATENCY LATEST` (LatencyCmd.readReply in command.go). The Redis docs require each latency event entry to be an array of at least 4 elements (name, timestamp, latest latency, all-time max latency). When the server returns a sub-array with fewer than 4 elements, go-redis refuses to parse it rather than index out of range, indicating either a non-standard/incompatible server or a corrupted/truncated reply.

Source

Thrown at command.go:5855

func (cmd *LatencyCmd) String() string {
	cmd.await()
	return cmdString(cmd, cmd.val)
}

func (cmd *LatencyCmd) readReply(rd *proto.Reader) error {
	n, err := rd.ReadArrayLen()
	if err != nil {
		return err
	}
	cmd.val = make([]Latency, n)
	for i := 0; i < len(cmd.val); i++ {
		nn, err := rd.ReadArrayLen()
		if err != nil {
			return err
		}
		if nn < 4 {
			return fmt.Errorf("redis: got %d elements in latency get, expected at least 4", nn)
		}
		if cmd.val[i].Name, err = rd.ReadString(); err != nil {
			return err
		}
		createdAt, err := rd.ReadInt()
		if err != nil {
			return err
		}
		cmd.val[i].Time = time.Unix(createdAt, 0)
		latest, err := rd.ReadInt()
		if err != nil {
			return err
		}
		cmd.val[i].Latest = time.Duration(latest) * time.Millisecond
		maximum, err := rd.ReadInt()
		if err != nil {
			return err
		}

View on GitHub (pinned to c5cad058c7)

Solutions

  1. Verify you are connecting to a real Redis server (run `INFO server` and check `redis_version`) rather than a proxy or Redis-compatible alternative.
  2. Upgrade the server to a recent Redis version that implements the full 4-field latency event format (name, timestamp, ms latest, ms all-time).
  3. If a proxy must be used, check whether it strips or rewrites LATENCY replies; either fix the proxy or disable latency monitoring against it.
  4. Capture the actual raw reply (e.g. with `redis-cli --raw LATENCY HISTORY <event>`) to confirm the shape the server sends before filing a bug.

Example fix

// before: mock reply with wrong arity for LATENCY HISTORY
mock.ExpectLatencyHistory([][]interface{}{{"event", 1700000000, 12}})

// after: each event entry must have >= 4 elements (name, ts, latest, max)
mock.ExpectLatencyHistory([][]interface{}{{"event", 1700000000, 12, 40}})
Defensive patterns

Strategy: try-catch

Validate before calling

// confirm server identity/capability before calling LATENCY
info, err := rdb.Info(ctx, "server").Result()
if err != nil || !strings.Contains(info, "redis_version:") {
    // not a standard Redis: skip latency monitoring
}

Try / catch

res, err := rdb.Latency(ctx, "HISTORY", event)
if err != nil {
    if strings.Contains(err.Error(), "elements in latency get") {
        // non-standard server reply: fall back to manual redis-cli/telemetry
        return nil, fmt.Errorf("latency history unavailable on this server: %w", err)
    }
    return nil, err
}

Prevention

When it happens

Trigger: Calling `client.Latency(ctx, "HISTORY", "event")` or `Latency(ctx, "LATEST", ...)` when the server replies with per-event arrays of fewer than 4 elements — e.g. a proxy/RESP translator, a Redis-compatible server (KeyDB, Dragonfly, Twemproxy) with a divergent LATENCY implementation, or a mocked/stubbed reply with the wrong shape.

Common situations: Pointing the client at a Redis-alternative or intermediate proxy that partially implements the LATENCY command; running a very old or non-standard server where LATENCY HISTORY returns 3-tuple entries; unit-test mocks returning simplified arrays.

Related errors


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