{"record":{"id":"8f26065d923aa863","repo":"thanos-io/thanos","slug":"get-postings","errorCode":null,"errorMessage":"get postings","messagePattern":"get postings","errorType":"exception","errorClass":null,"httpStatus":null,"severity":"error","filePath":"pkg/store/lazy_postings.go","lineNumber":306,"sourceCode":"\t\t\t}\n\t\t}\n\n\t\ti++\n\t}\n\n\treturn keys, lazyMatchers\n}\n\nfunc fetchAndExpandPostingGroups(ctx context.Context, r *bucketIndexReader, postingGroups []*postingGroup, bytesLimiter BytesLimiter, tenant string) ([]storage.SeriesRef, []*labels.Matcher, error) {\n\tkeys, lazyMatchers := keysToFetchFromPostingGroups(postingGroups)\n\tfetchedPostings, closeFns, err := r.fetchPostings(ctx, keys, bytesLimiter, tenant)\n\tdefer func() {\n\t\tfor _, closeFn := range closeFns {\n\t\t\tcloseFn()\n\t\t}\n\t}()\n\tif err != nil {\n\t\treturn nil, nil, errors.Wrap(err, \"get postings\")\n\t}\n\n\tresult := mergeFetchedPostings(ctx, fetchedPostings, postingGroups)\n\tif err := ctx.Err(); err != nil {\n\t\treturn nil, nil, err\n\t}\n\tps, err := ExpandPostingsWithContext(ctx, result)\n\tr.postings = ps\n\tif err != nil {\n\t\treturn nil, nil, errors.Wrap(err, \"expand\")\n\t}\n\treturn ps, lazyMatchers, nil\n}\n\nfunc mergeFetchedPostings(ctx context.Context, fetchedPostings []index.Postings, postingGroups []*postingGroup) index.Postings {\n\t// Get \"add\" and \"remove\" postings from groups. We iterate over postingGroups and their keys\n\t// again, and this is exactly the same order as before (when building the groups), so we can simply\n\t// use one incrementing index to fetch postings from returned slice.","sourceCodeStart":288,"sourceCodeEnd":324,"githubUrl":"https://github.com/thanos-io/thanos/blob/35b8b991177def87ed52dcf10f9b6d87f07282c8/pkg/store/lazy_postings.go#L288-L324","documentation":"fetchAndExpandPostingGroups in Thanos' lazy postings path fetches posting groups from the index and wraps any upstream fetch failure with \"get postings\". It indicates the underlying index (e.g. a bucket store block) failed to return postings for one of the query's matcher groups. The deferred loop closes all open resources before returning, so the failure is cleanup-safe.","triggerScenarios":"Calling fetchLazyExpandedPostings during a StoreAPI Series request when an underlying posting fetch fails (corrupt/missing index, network error fetching index from object storage, or a cancelled/expired context mid-fetch).","commonSituations":"Object storage throttling or timeouts when Thanos Store Gateway fetches index headers; deleted blocks whose index disappeared between listing and fetch; query cancellation when the request context deadline is exceeded.","solutions":["Inspect the wrapped inner error (%v) to find the root cause — network, object storage, or cancellation.","Retry the query; transient storage/network failures are the most common cause.","Verify block indexes in the bucket are intact and not deleted mid-query (check store-gateway blocks sync).","Increase query/store timeouts if the context deadline was the trigger."],"exampleFix":"// before\nres, err := store.Series(ctx, hints, matchers...)\n// after\nctx, cancel := context.WithTimeout(ctx, 2*time.Minute)\ndefer cancel()\nres, err := store.Series(ctx, hints, matchers...)\nif err != nil {\n  if errors.Is(err, context.DeadlineExceeded) { /* retry with longer timeout */ }\n}","handlingStrategy":"retry","validationCode":"if err := ctx.Err(); err != nil { return err } // ensure ctx alive before query\nif len(matchers) == 0 { return errors.New(\"need at least one matcher\") }","typeGuard":null,"tryCatchPattern":"if err != nil {\n  if errors.Is(err, context.Canceled) || errors.Is(err, context.DeadlineExceeded) {\n    // do not retry; caller gave up\n  } else if strings.Contains(err.Error(), \"get postings\") {\n    // retry with backoff against object storage\n  }\n}","preventionTips":["Set generous but bounded timeouts on store queries","Monitor object-storage error rates from store-gateway","Ensure bucket block GC doesn't delete blocks mid-query (grace periods)"],"tags":["go","index","storage"],"backgroundTag":"database-query-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"}