thanos-io/thanos · warning

not ready

Error message

not ready

What it means

Receive's Status server TSDB statistics getter checks httpProbe.IsReady() before serving TSDB stats. When the instance is not ready it returns errors.New("not ready") to the gRPC caller. Like the Info counterpart, this signals the process hasn't finished initialization or is terminating, and the request should be retried later.

Solutions

  1. Wait and retry once readiness (/-/ready) returns 200 on the target instance.
  2. Route status queries only to instances passing the readiness probe.
  3. Investigate slow readiness: disk performance, TSDB size, or blocking startup steps in logs.
  4. Add backoff/retry handling in the client for 'not ready' responses.
Defensive patterns

Strategy: retry

Validate before calling

// poll readiness before issuing status queries
if resp.StatusCode != 200 { return errors.New("receive instance not ready yet") }

Try / catch

stats, err := statusClient.TSDBStatistics(ctx, req)
if err != nil && strings.Contains(err.Error(), "not ready") {
  // retry with backoff or pick another ready replica
  time.Sleep(500 * time.Millisecond)
  stats, err = statusClient.TSDBStatistics(ctx, req)
}

Prevention

When it happens

Trigger: Invoking the Status/TSDB statistics gRPC endpoint on a receive instance whose readiness probe is false — during startup before TSDBs are opened, or during graceful shutdown.

Common situations: Dashboard or tooling querying /api/v1/status/tsdb via a receive replica that just started; load balancer routing to an unready pod; long TSDB startup behind slow disks.

Related errors


AI-assisted analysis of thanos-io/thanos@35b8b99117 (2026-09-07). Data as JSON: /api/errors/152ae5f12531ccf1. Report an issue: GitHub.

Appendix: source

Thrown at cmd/thanos/receive.go:416

						MinTime:                      minTime,
						MaxTime:                      maxTime,
						SupportsSharding:             true,
						SupportsWithoutReplicaLabels: true,
						TsdbInfos:                    proxy.TSDBInfos(),
					}, nil
				}
				return nil, errors.New("Not ready")
			}),
			info.WithExemplarsInfoFunc(),
			info.WithStatusInfoFunc(),
		)

		statusSrv := status.NewServer(
			component.Receive.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")
					}

					promMatchers, err := storepb.MatchersToPromMatchers(matchers...)
					if err != nil {
						return nil, errors.Wrap(err, "failed to convert matchers")
					}

					// Build the list of tenant IDs if the request matches
					// against exact tenant values only.
					var tenantIDs []string
					for _, promMatcher := range promMatchers {
						if promMatcher.Name != conf.tenantLabelName {
							continue
						}

						if promMatcher.Type != labels.MatchEqual {
							tenantIDs = nil
							break

View on GitHub (pinned to 35b8b99117)