{"record":{"id":"c28db553143d4735","repo":"thanos-io/thanos","slug":"scrape-manager-not-ready","errorCode":null,"errorMessage":"scrape manager not ready","messagePattern":"scrape manager not ready","errorType":"exception","errorClass":null,"httpStatus":null,"severity":"warning","filePath":"cmd/thanos/rule.go","lineNumber":1193,"sourceCode":"\tdefer rm.mtx.Unlock()\n\n\trm.m = m\n}\n\n// Get the scrape manager. If is not ready, return an error.\nfunc (rm *readyScrapeManager) Get() (*scrape.Manager, error) {\n\trm.mtx.RLock()\n\tdefer rm.mtx.RUnlock()\n\n\tif rm.m != nil {\n\t\treturn rm.m, nil\n\t}\n\n\treturn nil, ErrNotReady\n}\n\n// ErrNotReady is returned if the underlying scrape manager is not ready yet.\nvar ErrNotReady = errors.New(\"scrape manager not ready\")\n","sourceCodeStart":1175,"sourceCodeEnd":1194,"githubUrl":"https://github.com/thanos-io/thanos/blob/35b8b991177def87ed52dcf10f9b6d87f07282c8/cmd/thanos/rule.go#L1175-L1194","documentation":"ErrNotReady (\"scrape manager not ready\") is a sentinel error returned by the rule manager's Write method when the underlying scrape manager (the TSDB appender provider) has not finished initializing. Callers such as the rule evaluation path receive it instead of results and are expected to retry later; pkg/receive treats the sibling tsdb.ErrNotReady the same way by returning it upward.","triggerScenarios":"Calling ruleManager.Write (or an appender via the scrape manager) during Thanos rule startup before the scrape manager and its storage are ready, so the method short-circuits with `return nil, ErrNotReady` at cmd/thanos/rule.go:1189.","commonSituations":"Rule evaluation or query handling racing component startup (first evaluation ticks right after boot); slow TSDB WAL replay/block loading delaying readiness; running against a storage backend that is slow to open.","solutions":["Retry the operation after a delay — ErrNotReady is transient and resolves once the scrape manager finishes initializing.","Check `errors.Is(err, ErrNotReady)` (or tsdb.ErrNotReady) and treat it as a temporary condition rather than a fatal failure, mirroring pkg/receive/capnproto_writer.go's pattern.","Wait for Thanos rule logs indicating the scrape manager/TSDB is ready before driving evaluations.","If it persists indefinitely, investigate TSDB open failures (WAL corruption, disk issues) in startup logs."],"exampleFix":"// before\nsamples, err := rm.Write(ctx, q)\nif err != nil { return err }\n// after\nsamples, err := rm.Write(ctx, q)\nif errors.Is(err, ErrNotReady) {\n    time.Sleep(retryInterval)\n    return retry(ctx, q)\n}\nif err != nil { return err }","handlingStrategy":"retry","validationCode":"func isNotReady(err error) bool {\n    return errors.Is(err, ErrNotReady) || errors.Is(err, tsdb.ErrNotReady)\n}\n// gate writes on component readiness before calling","typeGuard":"func ready(err error) bool { return !errors.Is(err, ErrNotReady) }","tryCatchPattern":"samples, err := rm.Write(ctx, q)\nif errors.Is(err, ErrNotReady) {\n    select {\n    case <-time.After(backoff):\n    case <-ctx.Done():\n        return ctx.Err()\n    }\n    return retry(ctx, q) // transient: scrape manager still starting\n}\nif err != nil {\n    return err\n}","preventionTips":["Treat ErrNotReady as transient — always add bounded backoff retry around rule manager writes during startup","Sequence work after component readiness signals in startup logs rather than firing immediately","Distinguish ErrNotReady from other errors with errors.Is so only the transient case is retried"],"tags":["go","startup","not-ready","retry","thanos"],"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"}