{"record":{"id":"7855b48dd479ced7","repo":"thanos-io/thanos","slug":"get-appender","errorCode":null,"errorMessage":"get appender","messagePattern":"get appender","errorType":"exception","errorClass":null,"httpStatus":null,"severity":"error","filePath":"pkg/receive/capnproto_writer.go","lineNumber":56,"sourceCode":"\t\tmultiTSDB: multiTSDB,\n\t\topts:      opts,\n\t}\n}\n\nfunc (r *CapNProtoWriter) Write(ctx context.Context, wreq *writecapnp.Request) error {\n\ttLogger := log.With(r.logger, \"tenant\", wreq.Tenant)\n\n\ts, err := r.multiTSDB.TenantAppendable(wreq.Tenant)\n\tif err != nil {\n\t\treturn errors.Wrap(err, \"get tenant appendable\")\n\t}\n\n\tapp, err := s.Appender(ctx)\n\tif err == tsdb.ErrNotReady {\n\t\treturn err\n\t}\n\tif err != nil {\n\t\treturn errors.Wrap(err, \"get appender\")\n\t}\n\tgetRef := app.(storage.GetRef)\n\tvar (\n\t\tref          storage.SeriesRef\n\t\terrorTracker = &writeErrorTracker{}\n\t)\n\tapp = &ReceiveAppender{\n\t\ttLogger:        tLogger,\n\t\ttooFarInFuture: r.opts.TooFarInFutureTimeWindow,\n\t\tAppender:       app,\n\t}\n\n\tvar (\n\t\tseries  writecapnp.Series\n\t\tbuilder labels.ScratchBuilder\n\t)\n\tfor wreq.Next() {\n\t\tif err := wreq.At(&series); err != nil {","sourceCodeStart":38,"sourceCodeEnd":74,"githubUrl":"https://github.com/thanos-io/thanos/blob/35b8b991177def87ed52dcf10f9b6d87f07282c8/pkg/receive/capnproto_writer.go#L38-L74","documentation":"This error wraps a failure from the TSDB's Appender(ctx) call inside the Cap'n Proto receive writer. Thanos Receive first obtains a head Appender to buffer incoming samples; if the local TSDB cannot provide one (for any reason other than ErrNotReady, which is returned unwrapped for retry), the write fails with 'get appender'. It indicates the local storage head is not accepting appends right now.","triggerScenarios":"Calling CapNProtoWriter.Write when the embedded TSDB head is shutting down, corrupted, or its Appender() call fails for reasons other than tsdb.ErrNotReady (e.g. storage closed, OOM during head init).","commonSituations":"Receive pod shutting down while traffic still arrives; TSDB head compaction/startup in progress with a non-retryable failure; storage backend errors during appender acquisition; misconfigured storage paths on disk.","solutions":["Check the wrapped cause in the error chain for the underlying Appender failure","Verify the TSDB data directory is writable and not corrupted","Ensure Receive is not being shut down while still receiving traffic (check graceful termination order)","If tsdb.ErrNotReady is returned instead, wait for head readiness before retrying"],"exampleFix":"// before\napp, err := s.Appender(ctx)\nif err != nil { log.Error(err) }\n// after\napp, err := s.Appender(ctx)\nif errors.Is(err, tsdb.ErrNotReady) {\n\ttime.Sleep(backoff); return retry\n}\nif err != nil {\n\treturn errors.Wrap(err, \"get appender\")\n}","handlingStrategy":"retry","validationCode":"// no pre-call check possible; gate on readiness\nif s == nil || s.BlockStore == nil {\n\treturn errors.New(\"storage not initialized\")\n}","typeGuard":null,"tryCatchPattern":"app, err := w.Write(ctx, req)\nif errors.Is(err, tsdb.ErrNotReady) {\n\t// backoff and retry same batch\n} else if err != nil {\n\t// inspect wrapped cause via errors.Cause before giving up\n}","preventionTips":["Sequence shutdown so writers stop before the TSDB head closes","Monitor Receive readiness endpoints and drain traffic before restarts","Ensure the TSDB directory has adequate disk space and healthy I/O"],"tags":["tsdb","storage","write-path"],"backgroundTag":"database-write-failed","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"}