{"record":{"id":"de3ab41a75412ebc","repo":"thanos-io/thanos","slug":"new-index-reader","errorCode":null,"errorMessage":"new index reader","messagePattern":"new index reader","errorType":"error_code","errorClass":null,"httpStatus":null,"severity":"error","filePath":"pkg/block/indexheader/binary_reader.go","lineNumber":117,"sourceCode":"\t// PostingsOffsetTable holds start to the same Postings Offset Table section as index related to this index header.\n\tPostingsOffsetTable uint64\n}\n\n// WriteBinary build index header from the pieces of index in object storage, and cached in file if necessary.\nfunc WriteBinary(ctx context.Context, bkt objstore.BucketReader, id ulid.ULID, filename string, downloadDuration prometheus.Histogram) ([]byte, error) {\n\tstart := time.Now()\n\n\tdefer func() {\n\t\tdownloadDuration.Observe(time.Since(start).Seconds())\n\t}()\n\tvar tmpDir = \"\"\n\tif filename != \"\" {\n\t\ttmpDir = filepath.Dir(filename)\n\t}\n\tparallelBucket := WrapWithParallel(bkt, tmpDir)\n\tir, indexVersion, err := newChunkedIndexReader(ctx, parallelBucket, id)\n\tif err != nil {\n\t\treturn nil, errors.Wrap(err, \"new index reader\")\n\t}\n\ttmpFilename := \"\"\n\tif filename != \"\" {\n\t\ttmpFilename = filename + \".tmp\"\n\t}\n\n\t// Buffer for copying and encbuffers.\n\t// This also will control the size of file writer buffer.\n\tbuf := make([]byte, 32*1024)\n\tbw, err := newBinaryWriter(id, tmpFilename, buf)\n\tif err != nil {\n\t\treturn nil, errors.Wrap(err, \"new binary index header writer\")\n\t}\n\tdefer runutil.CloseWithErrCapture(&err, bw, \"close binary writer for %s\", tmpFilename)\n\n\tif err := bw.AddIndexMeta(indexVersion, ir.toc.PostingsTable); err != nil {\n\t\treturn nil, errors.Wrap(err, \"add index meta\")\n\t}","sourceCodeStart":99,"sourceCodeEnd":135,"githubUrl":"https://github.com/thanos-io/thanos/blob/35b8b991177def87ed52dcf10f9b6d87f07282c8/pkg/block/indexheader/binary_reader.go#L99-L135","documentation":"Thanos' indexheader.WriteBinary converts a block's index postings into a compact binary index-header file. This error wraps failure to create the chunked index reader over the block's index (via newChunkedIndexReader), i.e. the source index could not be opened/parsed to build the binary header.","triggerScenarios":"WriteBinary(ctx, bkt, id, filename) is called (directly or via NewBinaryReader/NewLazyBinaryReader) and newChunkedIndexReader fails: the block's index.bin is missing from the bucket or tmp dir, not downloadable, or its format/version cannot be parsed.","commonSituations":"Store gateway building an index-header cache for a block whose index.bin was deleted or still uploading; misconfigured bucket credentials/block ID causing fetch failures; index built by an unsupported Prometheus version.","solutions":["Verify the block ID and that index.bin exists and is fully uploaded in the bucket (check meta.json and the block directory)","Check object storage credentials/permissions for the bucket used to fetch the index","Re-download or re-sync the block from a healthy replica if index.bin is truncated","Ensure the block was produced by a supported Prometheus/Thanos index version"],"exampleFix":"// before\nif err := indexheader.WriteBinary(ctx, bkt, id, filename); err != nil {\n\treturn err\n}\n// after\nok, err := block.Exists(ctx, bkt, id)\nif err != nil { return err }\nif !ok { return errors.Errorf(\"block %s does not exist\", id) }\nif err := block.DownloadIndex(ctx, logger, bkt, id, dir); err != nil {\n\treturn errors.Wrap(err, \"download index\")\n}\nif err := indexheader.WriteBinary(ctx, bkt, id, filename); err != nil {\n\treturn errors.Wrap(err, \"write index header\")\n}","handlingStrategy":"fallback","validationCode":"ok, err := block.Exists(ctx, bkt, id)\nif err != nil { return err }\nif !ok { return errors.Errorf(\"block %s not found in bucket\", id) }\nif _, err := bkt.Get(ctx, path.Join(id.String(), block.IndexFilename)); err != nil {\n\treturn errors.Wrap(err, \"index.bin not fetchable\")\n}","typeGuard":"func indexAvailable(ctx context.Context, bkt objstore.Bucket, id ulid.ULID) bool {\n\trc, err := bkt.Get(ctx, path.Join(id.String(), block.IndexFilename))\n\tif err != nil { return false }\n\tdefer rc.Close()\n\treturn true\n}","tryCatchPattern":"hdr, err := indexheader.NewBinaryReader(ctx, logger, bkt, dir, id, cfg)\nif err != nil {\n\tif objstore.IsNotFoundError(errors.Cause(err)) {\n\t\t// block gone: refresh meta or remove from local cache and continue\n\t}\n\treturn errors.Wrapf(err, \"build index header for %s\", id)\n}","preventionTips":["Ensure blocks are fully uploaded (meta.json present) before readers process them","Check object-store credentials and network before batch index-header builds","Handle blocks disappearing from the bucket mid-operation; re-sync metadata first","Pin supported Prometheus index versions in compactor/store"],"tags":["thanos","indexheader","object-storage","block-index"],"backgroundTag":"file-read-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"}