thanos-io/thanos · error
proxy LabelNames()
Error message
proxy LabelNames()
What it means
LabelNames proxies the gRPC LabelNames RPC to all stores; any error returned by proxy.LabelNames is wrapped as 'proxy LabelNames()'. This is the umbrella error for store-side RPC failures during label name lookups.
Solutions
- Check store health and connectivity; inspect the wrapped RPC error
- Verify store address configuration and service discovery
- Increase query/store timeouts if under heavy load
- Retry once stores recover; check thanos query store status in UI/API
Defensive patterns
Strategy: retry
Validate before calling
// pre-check store reachability
if !allStoresHealthy(ctx, stores, 2*time.Second) {
return errors.New("stores unhealthy; skip LabelNames fan-out")
} Try / catch
names, warns, err := q.LabelNames(ctx, hints, matchers...)
if err != nil {
if strings.Contains(err.Error(), "proxy LabelNames()") {
return retryBackoff(ctx, 3, func() error { return fetchNames() })
}
return err
} Prevention
- Monitor gRPC connectivity to stores
- Use readiness probes so dead stores are removed from fan-out
- Set generous but bounded deadlines for LabelNames RPCs
When it happens
Trigger: Calling LabelNames while stores are unreachable, return remote errors, or the context deadline expires during the RPC fan-out.
Common situations: Store gateway restart, misconfigured store addresses, TLS handshake failures, heavy cardinality causing RPC timeouts.
Related errors
AI-assisted analysis of thanos-io/thanos@35b8b99117 (2026-09-07).
Data as JSON: /api/errors/732c89b8975c25c2.
Report an issue: GitHub.
Appendix: source
Thrown at pkg/query/querier.go:503
if hints == nil {
hints = &storage.LabelHints{}
}
req := &storepb.LabelNamesRequest{
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.LabelNames(ctx, req)
if err != nil {
return nil, nil, errors.Wrap(err, "proxy LabelNames()")
}
var warns annotations.Annotations
for _, w := range resp.Warnings {
warns.Add(errors.New(w))
}
return resp.Names, warns, nil
}
func (q *querier) Close() error { return nil }
// maxResolutionFromSelectHints finds the max possible resolution by inferring from the promql query.
func maxResolutionFromSelectHints(maxResolutionMillis int64, hintsRange int64, hintsFunc string) int64 {
if hintsRange > 0 {
if _, ok := promqlFuncRequiresTwoSamples[hintsFunc]; ok {
maxResolutionMillis = min(maxResolutionMillis, hintsRange/2)
}View on GitHub (pinned to 35b8b99117)