thanos-io/thanos · warning
res.GetWarning()
Error message
res.GetWarning()
What it means
metadataServer.Send is the streaming response sink; when the response carries a Warning string instead of data, it records that warning into srv.warnings via errors.New(res.GetWarning()). It surfaces upstream warnings from the metadata service to the caller.
Solutions
- Inspect srv.warnings after the call completes to see what was degraded
- Fix the underlying store error described in the warning text
- Use PartialResponseStrategy_ABORT if partial results with warnings are unacceptable
Defensive patterns
Strategy: try-catch
Try / catch
metadata, warnings, err := proxy.MetricMetadata(ctx, req)
if err == nil {
for _, w := range warnings {
log.Printf("metadata warning: %v", w)
}
} Prevention
- Always inspect the returned warnings slice, not just the error
- Decide upfront whether partial results (WARNING strategy) are acceptable
When it happens
Trigger: The metadata stream delivers a MetricMetadataResponse with a non-empty warning field, typically generated when a downstream store error was downgraded under PartialResponseStrategy_WARNING.
Common situations: Partial metadata results because one store shard failed; timeouts on part of the metadata scan reported as warnings.
Related errors
AI-assisted analysis of thanos-io/thanos@35b8b99117 (2026-09-07).
Data as JSON: /api/errors/bf35ef90409190cf.
Report an issue: GitHub.
Appendix: source
Thrown at pkg/metadata/metadata.go:79
type metadataServer struct {
// This field just exist to pseudo-implement the unused methods of the interface.
metadatapb.Metadata_MetricMetadataServer
ctx context.Context
metric string
limit int
warnings annotations.Annotations
metadataMap map[string][]metadatapb.Meta
mu sync.Mutex
}
func (srv *metadataServer) Send(res *metadatapb.MetricMetadataResponse) error {
if res.GetWarning() != "" {
srv.mu.Lock()
defer srv.mu.Unlock()
srv.warnings.Add(errors.New(res.GetWarning()))
return nil
}
if res.GetMetadata() == nil {
return errors.New("no metadata")
}
// If limit is set to 0, we don't need to add anything.
if srv.limit == 0 {
return nil
}
srv.mu.Lock()
defer srv.mu.Unlock()
for k, v := range res.GetMetadata().Metadata {
if metadata, ok := srv.metadataMap[k]; !ok {
// If limit is set and it is positive, we limit the size of the map.
if srv.limit < 0 || srv.limit > 0 && len(srv.metadataMap) < srv.limit {View on GitHub (pinned to 35b8b99117)