thanos-io/thanos · error

redis: Unexpected PING response

Error message

redis: Unexpected PING response %q

What it means

RedisClient.Ping converts the PING reply and expects the literal string "PONG". Any other string reply produces this formatted error including the unexpected response, indicating the peer is not behaving like a healthy Redis instance.

Solutions

  1. Inspect the %q value in the error to see what actually replied.
  2. Verify the endpoint reaches a real Redis server: run redis-cli PING manually.
  3. Remove or reconfigure any intermediary that intercepts PING.
  4. Confirm TLS/port settings match the server's protocol.

Example fix

// before
redis:
  endpoint: http-proxy:6379
// after
redis:
  endpoint: redis:6379
Defensive patterns

Strategy: try-catch

Try / catch

if err := client.Ping(ctx); err != nil {
    if strings.Contains(err.Error(), "Unexpected PING response") {
        log.Errorf("peer answered PING with something else — check for proxies: %v", err)
    }
    return err
}

Prevention

When it happens

Trigger: Calling Ping() and receiving a non-PONG string, e.g. a proxy/intermediary answering PING itself, or a resp-protocol variant whose reply text differs.

Common situations: Pointing the endpoint at an HTTP proxy or a different TCP service that echoes something else; connecting through a load balancer with a custom PING handler; misconfigured TLS wrapper returning its own banner.

Related errors


AI-assisted analysis of thanos-io/thanos@35b8b99117 (2026-09-07). Data as JSON: /api/errors/cee30ccf6fb838bf. Report an issue: GitHub.

Appendix: source

Thrown at internal/cortex/chunk/cache/redis_client.go:101

		timeout:    cfg.Timeout,
		rdb:        client,
	}, nil
}

func (c *RedisClient) Ping(ctx context.Context) error {
	var cancel context.CancelFunc
	if c.timeout > 0 {
		ctx, cancel = context.WithTimeout(ctx, c.timeout)
		defer cancel()
	}

	resp := c.rdb.Do(ctx, c.rdb.B().Ping().Build())
	pingResp, err := resp.ToString()
	if err != nil {
		return errors.New("converting PING response to string")
	}
	if pingResp != "PONG" {
		return errors.Errorf("redis: Unexpected PING response %q", pingResp)
	}
	return nil
}

func (c *RedisClient) MSet(ctx context.Context, keys []string, values [][]byte) error {
	var cancel context.CancelFunc
	if c.timeout > 0 {
		ctx, cancel = context.WithTimeout(ctx, c.timeout)
		defer cancel()
	}

	if len(keys) != len(values) {
		return errors.Errorf("MSet the length of keys and values not equal, len(keys)=%d, len(values)=%d", len(keys), len(values))
	}

	cmds := make(rueidis.Commands, 0, len(keys))
	for i := range keys {
		cmds = append(cmds, c.rdb.B().Set().Key(keys[i]).Value(rueidis.BinaryString(values[i])).Ex(c.expiration).Build())

View on GitHub (pinned to 35b8b99117)