thanos-io/thanos · error
not found key in results
Error message
not found key %s in results
What it means
RedisClient.MGet builds a reply map from the MGET response and requires every requested key to be present in that map. If a key is missing from the server's reply (protocol mismatch, key eviction race between request build and reply parse) it returns this error naming the key.
Solutions
- Deduplicate the key list before calling MGet — duplicates collapse in the reply map.
- Treat the missing key as a cache miss instead: wrap MGet and substitute nil for absent keys.
- Check for cluster/proxy behavior that truncates MGET replies and fall back to per-key GETs.
- Log the key from the error and verify it was part of the original request batch.
Example fix
// before
vals, err := client.MGet(ctx, keys)
// after: dedupe before the call
uniq := make([]string, 0, len(keys))
seen := map[string]struct{}{}
for _, k := range keys {
if _, ok := seen[k]; !ok { seen[k] = struct{}{}; uniq = append(uniq, k) }
}
vals, err := client.MGet(ctx, uniq) Defensive patterns
Strategy: fallback
Validate before calling
uniq := make([]string, 0, len(keys))
seen := map[string]struct{}{}
for _, k := range keys { if _, ok := seen[k]; !ok { seen[k] = struct{}{}; uniq = append(uniq, k) } }
keys = uniq Try / catch
vals, err := client.MGet(ctx, keys)
if err != nil && strings.Contains(err.Error(), "not found key") {
log.Warnf("treating MGet failure as cache miss: %v", err)
vals = nil // fall through to recompute and repopulate
} Prevention
- Deduplicate requested keys before MGet.
- Wrap MGet and degrade to cache-miss instead of failing queries.
- Use a cluster-aware client in Redis Cluster deployments.
When it happens
Trigger: Calling MGet(ctx, keys) and the returned rueidis reply map lacks one of the requested keys, so mgetRet[k] lookup fails with ok==false.
Common situations: Duplicate keys requested causing reply-map key collisions; proxy/cluster client dropping keys; mismatch between key list sent and reply parsed after a partial failure.
Understand the failure class
Background: Record Not Found Errors: "not found", RecordNotFound, and "was not found" — what they mean and how to fix them — this error's family across 28 libraries.
Related errors
- failed to convert resp to string
- creating redis client
- converting PING response to string
- redis: Unexpected PING response
- MSet the length of keys and values not equal, len(keys)=
AI-assisted analysis of thanos-io/thanos@35b8b99117 (2026-09-07).
Data as JSON: /api/errors/44612df97326b2ea.
Report an issue: GitHub.
Appendix: source
Thrown at internal/cortex/chunk/cache/redis_client.go:145
}
func (c *RedisClient) MGet(ctx context.Context, keys []string) ([][]byte, error) {
var cancel context.CancelFunc
if c.timeout > 0 {
ctx, cancel = context.WithTimeout(ctx, c.timeout)
defer cancel()
}
ret := make([][]byte, 0, len(keys))
mgetRet, err := rueidis.MGet(c.rdb, ctx, keys)
if err != nil {
return nil, err
}
for _, k := range keys {
m, ok := mgetRet[k]
if !ok {
return nil, errors.Errorf("not found key %s in results", k)
}
if m.IsNil() {
ret = append(ret, nil)
continue
}
r, err := m.ToString()
if err != nil {
return nil, errors.Errorf("failed to convert %s resp to string", k)
}
ret = append(ret, stringToBytes(r))
}
return ret, nil
}
func (c *RedisClient) Close() error {
c.rdb.Close()
return nilView on GitHub (pinned to 35b8b99117)