thanos-io/thanos · error
proxy LabelValues()
Error message
proxy LabelValues()
What it means
LabelValues fans out to stores through the gRPC proxy; any error from proxy.LabelValues (transport failure, remote error, deadline) is wrapped as 'proxy LabelValues()'. It's the umbrella error for store-side failures during label value lookup.
Solutions
- Check store endpoint health/connectivity (grpcurl, logs)
- Review the wrapped underlying error for which store failed
- Raise timeouts or reduce label matcher scope for large cardinality labels
- Ensure network policies/firewalls allow gRPC on store ports
Defensive patterns
Strategy: retry
Validate before calling
// verify at least one healthy store before LabelValues fan-out
if len(healthyStores(stores)) == 0 {
return errors.New("no healthy stores for LabelValues")
} Try / catch
vals, warns, err := q.LabelValues(ctx, name, hints, matchers...)
if err != nil {
if strings.Contains(err.Error(), "proxy LabelValues()") {
return retryBackoff(ctx, 3, func() error { return fetchValues() })
}
return err
} Prevention
- Alert on store RPC failure rate
- Keep query timeouts above store latency p99
- Ensure service discovery excludes dead stores promptly
When it happens
Trigger: Calling LabelValues while one or more queried stores fail the LabelValues RPC: unreachable endpoints, TLS errors, context deadline exceeded.
Common situations: Store gateway outage, Kubernetes service DNS issues, query frontend timeout too short, network policies blocking gRPC traffic.
Related errors
AI-assisted analysis of thanos-io/thanos@35b8b99117 (2026-09-07).
Data as JSON: /api/errors/69be1c691dd28ab1.
Report an issue: GitHub.
Appendix: source
Thrown at pkg/query/querier.go:460
hints = &storage.LabelHints{}
}
req := &storepb.LabelValuesRequest{
Label: name,
PartialResponseStrategy: q.partialResponseStrategy,
Start: q.mint,
End: q.maxt,
Matchers: pbMatchers,
Limit: int64(hints.Limit),
}
if q.isDedupEnabled() {
req.WithoutReplicaLabels = q.replicaLabels
}
resp, err := q.proxy.LabelValues(ctx, req)
if err != nil {
return nil, nil, errors.Wrap(err, "proxy LabelValues()")
}
var warns annotations.Annotations
for _, w := range resp.Warnings {
warns.Add(errors.New(w))
}
return resp.Values, warns, nil
}
// LabelNames returns all the unique label names present in the block in sorted order constrained
// by the given matchers.
func (q *querier) LabelNames(ctx context.Context, hints *storage.LabelHints, matchers ...*labels.Matcher) ([]string, annotations.Annotations, error) {
span, ctx := tracing.StartSpan(ctx, "querier_label_names")
defer span.Finish()
// TODO(bwplotka): Pass it using the SeriesRequest instead of relying on context.
ctx = context.WithValue(ctx, store.StoreMatcherKey, q.storeDebugMatchers)View on GitHub (pinned to 35b8b99117)