{"record":{"id":"cb6dc0c3d47ab885","repo":"thanos-io/thanos","slug":"range-not-found","errorCode":null,"errorMessage":"range not found","messagePattern":"range not found","errorType":"error_code","errorClass":null,"httpStatus":null,"severity":"info","filePath":"pkg/block/indexheader/header.go","lineNumber":15,"sourceCode":"// Copyright (c) The Thanos Authors.\n// Licensed under the Apache License 2.0.\n\npackage indexheader\n\nimport (\n\t\"context\"\n\t\"io\"\n\n\t\"github.com/pkg/errors\"\n\t\"github.com/prometheus/prometheus/tsdb/index\"\n)\n\n// NotFoundRangeErr is an error returned by PostingsOffset when there is no posting for given name and value pairs.\nvar NotFoundRangeErr = errors.New(\"range not found\")\n\n// Reader is an interface allowing to read essential, minimal number of index fields from the small portion of index file called header.\ntype Reader interface {\n\tio.Closer\n\n\t// IndexVersion returns version of index.\n\tIndexVersion() (int, error)\n\n\t// PostingsOffsets returns start and end offsets for postings for given name and values.\n\t// Input values need to be sorted.\n\t// If the requested label name doesn't exist, then no posting and error will be returned.\n\t// If the requested label name exists, but some values don't exist, the corresponding index range\n\t// will be set to -1 for both start and end.\n\tPostingsOffsets(name string, value ...string) ([]index.Range, error)\n\n\t// PostingsOffset returns start and end offsets of postings for given name and value.\n\t// The end offset might be bigger than the actual posting ending, but not larger than the whole index file.\n\t// NotFoundRangeErr is returned when no index can be found for given name and value.","sourceCodeStart":1,"sourceCodeEnd":33,"githubUrl":"https://github.com/thanos-io/thanos/blob/35b8b991177def87ed52dcf10f9b6d87f07282c8/pkg/block/indexheader/header.go#L1-L33","documentation":"Sentinel error NotFoundRangeErr returned by Reader.PostingsOffset when the index header has no posting range for the given label name/value pair. Signals a legitimate miss (symbol/label not in the index), used by callers for existence checks, not an unexpected failure.","triggerScenarios":"Calling br.PostingsOffset(\"name\",\"value\") for a label name or value combination that does not exist in the block's postings table (e.g. \"not-existing\",\"1\" in tests).","commonSituations":"Querier/store-gateway asking a block for series that this block simply doesn't contain; typos in label names; querying time-ranged blocks outside their data.","solutions":["Treat it as 'no data for this label pair in this block' and skip the block (errors.Is(err, indexheader.NotFoundRangeErr))","Verify the label name/value spelling and casing","Check you are querying blocks that actually cover the requested data"],"exampleFix":"// before\nrng, err := br.PostingsOffset(\"job\", \"node\")\nif err != nil { return err }\n// after\nrng, err := br.PostingsOffset(\"job\", \"node\")\nif errors.Is(err, indexheader.NotFoundRangeErr) { return nil // block lacks this posting\n}\nif err != nil { return err }","handlingStrategy":"type-guard","validationCode":null,"typeGuard":null,"tryCatchPattern":"rng, err := br.PostingsOffset(name, value)\nif errors.Is(err, indexheader.NotFoundRangeErr) { return nil /* expected: label pair absent */ }\nif err != nil { return err }","preventionTips":["Always compare with errors.Is/Equals against NotFoundRangeErr instead of string matching","Remember missing label names/values in a block are normal — skip the block","Check block time range and label set before assuming data should exist"],"tags":["tsdb","postings","not-found","sentinel-error"],"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"}