thanos-io/thanos · error · ApiError
retrieving metadata
Error message
retrieving metadata
What it means
Wraps any failure from the store client's MetricMetadata gRPC call during /api/v1/metadata handling. It is classified as an internal error (ErrorInternal), meaning the query-side plumbing failed rather than the request being bad.
Solutions
- Check querier-to-store connectivity and that store gateways are healthy (`thanos tools bucket verify`, store /-/healthy).
- Inspect querier logs for the wrapped root cause; retry the request.
- Verify store gRPC services are registered and the Querier's store address set includes reachable endpoints.
Defensive patterns
Strategy: retry
Try / catch
const resp = await fetch(`${base}/api/v1/metadata?limit=100`);
if (!resp.ok) {
const body = await resp.json();
if (body.errorType === 'internal') {
// check store health, then retry with backoff
await sleep(backoff);
return retry();
}
throw new Error(body.error);
} Prevention
- Monitor store gateway health and querier-store connectivity.
- Set generous gRPC timeouts for metadata calls.
- Alert on store node restarts/OOMs.
When it happens
Trigger: The store/storeAPI backing the querier returns an error or the RPC fails while fetching metric metadata (network drop, store unavailable, store-side limit/parse errors).
Common situations: Store gateway down or restarting, network partitions between querier and store, timeouts on large metadata sets, store nodes returning gRPC errors.
Related errors
- retrieving tsdb statistics
- cannot obtain metadata: neither info nor store client found
- could not sync metas
- building gRPC client
- read meta
AI-assisted analysis of thanos-io/thanos@35b8b99117 (2026-09-07).
Data as JSON: /api/errors/c6ccf62f2d04b472.
Report an issue: GitHub.
Appendix: source
Thrown at pkg/api/query/v1.go:1681
Limit: -1,
Metric: r.URL.Query().Get("metric"),
PartialResponseStrategy: ps,
}
limitStr := r.URL.Query().Get("limit")
if limitStr != "" {
limit, err := strconv.ParseInt(limitStr, 10, 32)
if err != nil {
return nil, nil, &api.ApiError{Typ: api.ErrorBadData, Err: errors.Errorf("invalid metric metadata limit='%v'", limit)}, func() {}
}
req.Limit = int32(limit)
}
tracing.DoInSpan(ctx, "retrieve_metadata", func(ctx context.Context) {
t, warnings, err = client.MetricMetadata(ctx, req)
})
if err != nil {
return nil, nil, &api.ApiError{Typ: api.ErrorInternal, Err: errors.Wrap(err, "retrieving metadata")}, func() {}
}
return t, warnings.AsErrors(), nil, func() {}
}
}
func (qapi *QueryAPI) tsdbStatus(r *http.Request) (any, []error, *api.ApiError, func()) {
span, ctx := tracing.StartSpan(r.Context(), "tsdb_statistics_query_request")
defer span.Finish()
if err := r.ParseForm(); err != nil {
return nil, nil, &api.ApiError{Typ: api.ErrorInternal, Err: errors.Wrap(err, "parse form")}, func() {}
}
ps := storepb.PartialResponseStrategy_ABORT
if qapi.enableStatusPartialResponse {
ps = storepb.PartialResponseStrategy_WARN
}View on GitHub (pinned to 35b8b99117)