{"record":{"id":"f61910050905ea38","repo":"thanos-io/thanos","slug":"read-series-range","errorCode":null,"errorMessage":"read series range","messagePattern":"read series range","errorType":"exception","errorClass":null,"httpStatus":null,"severity":"error","filePath":"pkg/store/bucket.go","lineNumber":3399,"sourceCode":"\t\t})\n\t}\n\treturn g.Wait()\n}\n\nfunc (r *bucketIndexReader) loadSeries(ctx context.Context, ids []storage.SeriesRef, refetch bool, start, end uint64, bytesLimiter BytesLimiter, tenant string) error {\n\tbegin := time.Now()\n\tstats := new(queryStats)\n\tdefer func() {\n\t\tr.stats.merge(stats)\n\t}()\n\n\tif err := bytesLimiter.ReserveWithType(uint64(end-start), SeriesFetched); err != nil {\n\t\treturn httpgrpc.Errorf(int(codes.ResourceExhausted), \"exceeded bytes limit while fetching series: %s\", err)\n\t}\n\n\tb, err := r.block.readIndexRange(ctx, int64(start), int64(end-start), r.logger)\n\tif err != nil {\n\t\treturn errors.Wrap(err, \"read series range\")\n\t}\n\n\tstats.seriesFetchCount++\n\tstats.SeriesFetchDurationSum += time.Since(begin)\n\tstats.add(SeriesFetched, len(ids), int(end-start))\n\n\tfor i, id := range ids {\n\t\tc := b[uint64(id)-start:]\n\n\t\tl, n := binary.Uvarint(c)\n\t\tif n < 1 {\n\t\t\treturn errors.New(\"reading series length failed\")\n\t\t}\n\t\tif len(c) < n+int(l) {\n\t\t\tif i == 0 && refetch {\n\t\t\t\treturn errors.Errorf(\"invalid remaining size, even after refetch, remaining: %d, expected %d\", len(c), n+int(l))\n\t\t\t}\n","sourceCodeStart":3381,"sourceCodeEnd":3417,"githubUrl":"https://github.com/thanos-io/thanos/blob/35b8b991177def87ed52dcf10f9b6d87f07282c8/pkg/store/bucket.go#L3381-L3417","documentation":"Loading series (Series/Lookup) fetches a byte range of the block index via r.block.readIndexRange, which may consult cache or do a ranged object-storage GET. This error wraps any failure fetching that byte range — cache miss failure, object missing, network error, or throttling — for the requested series ids range.","triggerScenarios":"r.block.readIndexRange(ctx, start, end-start, logger) fails during LoadSeries: object-storage ranged GET error, series cache (store.index-cache.series) fetch error, or context cancellation while fetching.","commonSituations":"Heavy series fan-out queries exceeding bucket request rate limits; index object deleted while being read; misconfigured or unavailable external series cache; network timeouts on large ranges.","solutions":["Retry the query; verify whether the error is transient (network/throttle) or persistent (missing object)","Check that the block and its index still exist in the bucket and is not deleted mid-query","Inspect and fix the series cache backend configuration, or clear corrupted cache entries","Look at the wrapped error to distinguish permission issues (fix IAM) from network issues (fix connectivity)"],"exampleFix":null,"handlingStrategy":"retry","validationCode":"if end <= start || uint64(end) > indexFileSize {\n\t// invalid range: do not call readIndexRange\n}","typeGuard":"func validRange(start, end uint64, size uint64) bool { return start < end && end <= size }","tryCatchPattern":"b, err := r.block.readIndexRange(ctx, int64(start), int64(end-start), r.logger)\nif err != nil {\n\tif isTransient(err) {\n\t\tb, err = retryFetch(ctx, start, end)\n\t}\n\tif err != nil { return errors.Wrap(err, \"read series range\") }\n}","preventionTips":["Tune series cache to avoid stale/corrupt entries","Configure bucket retries/backoff for throttling","Check index object existence before large fan-out reads","Alert on seriesRefetches and fetch error rates"],"tags":["thanos","series","object-storage","network","index"],"backgroundTag":"network-request-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"}