thanos-io/thanos · warning
%s
Error message
%s
What it means
exemplarsServer.Send is the streaming receiver for ExemplarsResponse messages from downstream store/proxy servers. When a response carries a warning string instead of data, the server collects it via a multierror and returns nil so the stream continues. The message text is the warning itself ("%s"), propagated from a downstream server; this specific errors.New only fires for "empty exemplars data" — the family here is the streamed-warning path where GetWarning() != "".
Solutions
- Inspect resp.warnings returned from Exemplars(); the actual cause is the wrapped warning text from the failing downstream store.
- Check health/logs of the store API endpoints that produced the warning (unreachable stores, unsupported exemplar endpoints).
- If failures should be fatal, switch the query to PartialResponseStrategy_ABORT so errors abort instead of becoming warnings.
- Fix the underlying store error (often 'exemplars not supported' on older store gateways).
Defensive patterns
Strategy: try-catch
Try / catch
data, warnings, err := client.Exemplars(ctx, req)
if err != nil {
// fatal path (ABORT strategy)
return err
}
for _, w := range warnings {
log.Warnf("exemplars warning: %v", w)
}
// still use partial `data` Prevention
- Always inspect the returned warnings slice, not just the error.
- Decide explicitly between ABORT (fail fast) and tolerant partial-response strategies.
- Monitor store health so warning sources are detected early.
When it happens
Trigger: A downstream Exemplars server sends exemplarspb.NewWarningExemplarsResponse (e.g. from a partial-response failure in the proxy's receive loop); srv.Send observes res.GetWarning() != "" and accumulates it instead of failing.
Common situations: Query frontends with PartialResponseStrategy_WARMUP/`true` partial responses where some storeAPIs fail; the client sees warnings aggregated alongside partial exemplar data.
Related errors
AI-assisted analysis of thanos-io/thanos@35b8b99117 (2026-09-07).
Data as JSON: /api/errors/74a02ef83f0948b2.
Report an issue: GitHub.
Appendix: source
Thrown at pkg/exemplars/exemplars.go:49
replicaLabels map[string]struct{}
}
type exemplarsServer struct {
// This field just exist to pseudo-implement the unused methods of the interface.
exemplarspb.Exemplars_ExemplarsServer
ctx context.Context
warnings annotations.Annotations
data []*exemplarspb.ExemplarData
mu sync.Mutex
}
func (srv *exemplarsServer) Send(res *exemplarspb.ExemplarsResponse) error {
if res.GetWarning() != "" {
srv.mu.Lock()
defer srv.mu.Unlock()
srv.warnings.Add(errors.New(res.GetWarning()))
return nil
}
if res.GetData() == nil {
return errors.New("empty exemplars data")
}
srv.mu.Lock()
defer srv.mu.Unlock()
srv.data = append(srv.data, res.GetData())
return nil
}
func (srv *exemplarsServer) Context() context.Context {
return srv.ctx
}
func NewGRPCClient(es exemplarspb.ExemplarsServer) *GRPCClient {View on GitHub (pinned to 35b8b99117)