thanos-io/thanos · error
bad cached type
Error message
bad cached type
What it means
toResponse unmarshals a cached Any-wrapped protobuf message and asserts it implements the queryrange.Response interface. If the cached entry's type name decodes to a message that is not a known Response type (corrupt or foreign cache entry), it returns "bad cached type".
Solutions
- Flush the results cache (memcached/redis) after version upgrades
- Ensure all frontend replicas run the same Cortex version during rollouts
- Add a cache key version prefix so old entries are ignored
Example fix
// before: shared cache across versions with same keys
// after: bump cache key version
cacheKey := fmt.Sprintf("v2:%s:%s", userID, req.GetQuery()) Defensive patterns
Strategy: try-catch
Type guard
if resp, ok := msg.(queryrange.Response); !ok {
return fmt.Errorf("bad cached type %T", msg)
} Try / catch
resp, err := toResponse(e.Response)
if err != nil && strings.Contains(err.Error(), "bad cached type") {
cache.Delete(key) // evict poisoned entry and re-fetch upstream
return upstreamHandler(ctx, req)
} Prevention
- Flush shared caches on Cortex version upgrades
- Version cache keys so old-format entries are never read
- Run homogeneous frontend versions during rollouts
When it happens
Trigger: Reading a results-cache entry whose stored type URL was written by a different queryrange version/schema, or whose bytes were corrupted, so msg.(Response) fails in newAccumulator.
Common situations: Upgrading/downgrading Cortex while sharing the same memcached/redis cache; cache poisoned by a mixed-version fleet during rolling deploy; manually populated or flushed-incompatible cache backends.
Related errors
- invalid duration
- use of multiple cache storage systems is not supported
- unsupported compression type
- at modifier after end
- negative offset
AI-assisted analysis of thanos-io/thanos@35b8b99117 (2026-09-07).
Data as JSON: /api/errors/c57d4c0dc5cb2484.
Report an issue: GitHub.
Appendix: source
Thrown at internal/cortex/querier/queryrange/results_cache.go:871
if ts < start || ts > end {
return false
}
return step <= 0 || (ts-start)%step == 0
}
func (e *Extent) toResponse() (Response, error) {
msg, err := types.EmptyAny(e.Response)
if err != nil {
return nil, err
}
if err := types.UnmarshalAny(e.Response, msg); err != nil {
return nil, err
}
resp, ok := msg.(Response)
if !ok {
return nil, fmt.Errorf("bad cached type")
}
return resp, nil
}
View on GitHub (pinned to 35b8b99117)