{"record":{"id":"152ae5f12531ccf1","repo":"thanos-io/thanos","slug":"not-ready-152ae5","errorCode":null,"errorMessage":"not ready","messagePattern":"not ready","errorType":"exception","errorClass":null,"httpStatus":null,"severity":"warning","filePath":"cmd/thanos/receive.go","lineNumber":416,"sourceCode":"\t\t\t\t\t\tMinTime:                      minTime,\n\t\t\t\t\t\tMaxTime:                      maxTime,\n\t\t\t\t\t\tSupportsSharding:             true,\n\t\t\t\t\t\tSupportsWithoutReplicaLabels: true,\n\t\t\t\t\t\tTsdbInfos:                    proxy.TSDBInfos(),\n\t\t\t\t\t}, nil\n\t\t\t\t}\n\t\t\t\treturn nil, errors.New(\"Not ready\")\n\t\t\t}),\n\t\t\tinfo.WithExemplarsInfoFunc(),\n\t\t\tinfo.WithStatusInfoFunc(),\n\t\t)\n\n\t\tstatusSrv := status.NewServer(\n\t\t\tcomponent.Receive.String(),\n\t\t\tstatus.WithTSDBStatisticsGetter(\n\t\t\t\tstatus.TSDBStatisticsGetterFunc(func(limit int, matchers []storepb.LabelMatcher) (map[string]tsdb.Stats, error) {\n\t\t\t\t\tif !httpProbe.IsReady() {\n\t\t\t\t\t\treturn nil, errors.New(\"not ready\")\n\t\t\t\t\t}\n\n\t\t\t\t\tpromMatchers, err := storepb.MatchersToPromMatchers(matchers...)\n\t\t\t\t\tif err != nil {\n\t\t\t\t\t\treturn nil, errors.Wrap(err, \"failed to convert matchers\")\n\t\t\t\t\t}\n\n\t\t\t\t\t// Build the list of tenant IDs if the request matches\n\t\t\t\t\t// against exact tenant values only.\n\t\t\t\t\tvar tenantIDs []string\n\t\t\t\t\tfor _, promMatcher := range promMatchers {\n\t\t\t\t\t\tif promMatcher.Name != conf.tenantLabelName {\n\t\t\t\t\t\t\tcontinue\n\t\t\t\t\t\t}\n\n\t\t\t\t\t\tif promMatcher.Type != labels.MatchEqual {\n\t\t\t\t\t\t\ttenantIDs = nil\n\t\t\t\t\t\t\tbreak","sourceCodeStart":398,"sourceCodeEnd":434,"githubUrl":"https://github.com/thanos-io/thanos/blob/35b8b991177def87ed52dcf10f9b6d87f07282c8/cmd/thanos/receive.go#L398-L434","documentation":"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.","triggerScenarios":"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.","commonSituations":"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.","solutions":["Wait and retry once readiness (/-/ready) returns 200 on the target instance.","Route status queries only to instances passing the readiness probe.","Investigate slow readiness: disk performance, TSDB size, or blocking startup steps in logs.","Add backoff/retry handling in the client for 'not ready' responses."],"exampleFix":null,"handlingStrategy":"retry","validationCode":"// poll readiness before issuing status queries\nif resp.StatusCode != 200 { return errors.New(\"receive instance not ready yet\") }","typeGuard":null,"tryCatchPattern":"stats, err := statusClient.TSDBStatistics(ctx, req)\nif err != nil && strings.Contains(err.Error(), \"not ready\") {\n  // retry with backoff or pick another ready replica\n  time.Sleep(500 * time.Millisecond)\n  stats, err = statusClient.TSDBStatistics(ctx, req)\n}","preventionTips":["Query status APIs only on ready replicas","Configure load balancers to respect readiness probes","Implement client-side retry for 'not ready' errors","Alert on long-running unready receive instances"],"tags":["grpc","readiness","status","transient"],"backgroundTag":"service-not-ready","analyzedSha":"35b8b991177def87ed52dcf10f9b6d87f07282c8","analyzedAt":"2026-09-07T01:49:59.689Z","contentChangedAt":"2026-09-07T01:49:59.689Z","schemaVersion":2},"datasetVersion":"2026-09-15T23:17:13.987Z"}