thanos-io/thanos · warning
not ready
Error message
not ready
What it means
The Status gRPC server's TSDB statistics getter returns errors.New("not ready") when the rule component's HTTP readiness probe (httpProbe.IsReady()) is still false. Any TSDBStats RPC issued before the component reports ready fails with this error instead of computing stats.
Solutions
- Wait for /-/ready to return OK, then retry the status request.
- If it persists, check logs for the underlying reason the probe is not ready (failed rule reload, TSDB issues).
- Add retry/backoff around status API calls in automation.
- Fix the failed reload (e.g. invalid rule file from error 139) so the component becomes ready.
Defensive patterns
Strategy: retry
Validate before calling
await fetch('http://rule:10902/-/ready').then(r => r.ok) Try / catch
try { stats = await statusClient.TSDBStats(req) } catch (e) { if (String(e).includes('not ready')) { await waitForReady(); return retry() } throw e } Prevention
- Poll /-/ready before calling status APIs
- Fix underlying not-ready causes (failed reloads) promptly
- Add retry/backoff in dashboards and automation
When it happens
Trigger: A client calls the TSDB status/statistics RPC while the rule component is starting up or has been marked not ready (e.g. during a failed reload that set the probe unhealthy).
Common situations: Opening the Thanos UI/bucket status page right after pod restart; monitoring tooling polling the status API before readiness; component stuck not-ready due to a config reload failure.
Related errors
AI-assisted analysis of thanos-io/thanos@35b8b99117 (2026-09-07).
Data as JSON: /api/errors/620626898225d2d8.
Report an issue: GitHub.
Appendix: source
Thrown at cmd/thanos/rule.go:793
SupportsSharding: true,
SupportsWithoutReplicaLabels: true,
TsdbInfos: tsdbStore.TSDBInfos(),
}, nil
}
return nil, errors.New("Not ready")
}),
info.WithStatusInfoFunc(),
)
storeServer := store.NewLimitedStoreServer(store.NewInstrumentedStoreServer(reg, tsdbStore), reg, conf.storeRateLimits)
options = append(options, grpcserver.WithServer(store.RegisterStoreServer(storeServer, logger)))
// Add Status server for TSDB statistics
statusSrv := status.NewServer(
component.Rule.String(),
status.WithTSDBStatisticsGetter(
status.TSDBStatisticsGetterFunc(func(limit int, matchers []storepb.LabelMatcher) (map[string]tsdb.Stats, error) {
if !httpProbe.IsReady() {
return nil, errors.New("not ready")
}
// Check if external labels match the provided matchers.
extLabels := conf.lset
promMatchers, err := storepb.MatchersToPromMatchers(matchers...)
if err != nil {
return nil, errors.Wrap(err, "failed to convert matchers")
}
for _, matcher := range promMatchers {
if !matcher.Matches(extLabels.Get(matcher.Name)) {
// External labels don't match, return empty result.
return nil, nil
}
}
stats := tsdbDB.Head().Stats(labels.MetricName, limit)
return map[string]tsdb.Stats{
"": *stats,View on GitHub (pinned to 35b8b99117)