{"record":{"id":"05dc17c1d16dfee9","repo":"thanos-io/thanos","slug":"get-tenant-appendable","errorCode":null,"errorMessage":"get tenant appendable","messagePattern":"get tenant appendable","errorType":"exception","errorClass":null,"httpStatus":null,"severity":"error","filePath":"pkg/receive/writer.go","lineNumber":79,"sourceCode":"}\n\nfunc NewWriter(logger log.Logger, multiTSDB TenantStorage, opts *WriterOptions) *Writer {\n\tif opts == nil {\n\t\topts = &WriterOptions{}\n\t}\n\treturn &Writer{\n\t\tlogger:    logger,\n\t\tmultiTSDB: multiTSDB,\n\t\topts:      opts,\n\t}\n}\n\nfunc (r *Writer) Write(ctx context.Context, tenantID string, wreq []prompb.TimeSeries) error {\n\ttLogger := log.With(r.logger, \"tenant\", tenantID)\n\n\ts, err := r.multiTSDB.TenantAppendable(tenantID)\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,","sourceCodeStart":61,"sourceCodeEnd":97,"githubUrl":"https://github.com/thanos-io/thanos/blob/35b8b991177def87ed52dcf10f9b6d87f07282c8/pkg/receive/writer.go#L61-L97","documentation":"Error from Thanos receive Writer.Write: the multi-TSDB could not return an Appendable for the given tenant (multiTSDB.TenantAppendable failed). This usually means the tenant is unknown/not allowed, the tenant ID is invalid, or the per-tenant TSDB cannot be opened/created.","triggerScenarios":"Writer.Write called with a tenantID for which TenantAppendable returns an error - e.g. tenant not matching allowed tenants configuration, illegal tenant label characters, or failure opening/creating the tenant's TSDB directory.","commonSituations":"Remote-write senders using a tenant header (e.g. thanos tenant: X-Scope-OrgID) that isn't in the receiver's allowed list; typo'd tenant IDs; disk/permission problems preventing per-tenant TSDB creation.","solutions":["Check the wrapped cause to see if it is tenant validation or TSDB open failure.","Verify the tenant ID against the receive --receive.tenant-header / allowed tenants config and fix the sender's header value.","Ensure the TSDB data directory is writable and has disk space.","Confirm the multiTSDB was initialized with the tenant (hashrings/replication config) before writes."],"exampleFix":"// before: arbitrary tenant from header\ntenant := r.Header.Get(\"X-Scope-OrgID\") // \"foo bar\" (invalid)\n// after: validate against allowlist\nif !allowedTenants[tenant] { http.Error(w, \"unknown tenant\", 400); return }","handlingStrategy":"validation","validationCode":"if tenant == \"\" || !validTenantRegex.MatchString(tenant) {\n    return errors.New(\"invalid or missing tenant ID\")\n}\nif !allowedTenants[tenant] { return fmt.Errorf(\"tenant %q not allowed\", tenant) }","typeGuard":null,"tryCatchPattern":"if err := writer.Write(ctx, tenant, series); err != nil {\n    if strings.Contains(err.Error(), \"get tenant appendable\") {\n        // reject request with 400/404, do not retry against same tenant\n    }\n}","preventionTips":["Validate tenant header against allowlist before routing","Use a strict tenant ID regex (no slashes/spaces)","Keep hashring/tenant config in sync between router and receiver"],"tags":["thanos","receive","multi-tenancy","tsdb","go"],"backgroundTag":"resource-not-found","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"}