{"record":{"id":"86e2a9a33556e27c","repo":"thanos-io/thanos","slug":"index-header-s-header","errorCode":null,"errorMessage":"index header's header","messagePattern":"index header's header","errorType":"error_code","errorClass":null,"httpStatus":null,"severity":"error","filePath":"pkg/block/indexheader/binary_reader.go","lineNumber":671,"sourceCode":"\tif err := d.Err(); err != nil {\n\t\treturn nil, err\n\t}\n\n\treturn &BinaryTOC{\n\t\tSymbols:             d.Be64(),\n\t\tPostingsOffsetTable: d.Be64(),\n\t}, nil\n}\n\nfunc (r *BinaryReader) init() (err error) {\n\tstart := time.Now()\n\n\tdefer func() {\n\t\tr.metrics.loadDuration.Observe(time.Since(start).Seconds())\n\t}()\n\t// Verify header.\n\tif r.b.Len() < headerLen {\n\t\treturn errors.Wrap(encoding.ErrInvalidSize, \"index header's header\")\n\t}\n\tif m := binary.BigEndian.Uint32(r.b.Range(0, 4)); m != MagicIndex {\n\t\treturn errors.Errorf(\"invalid magic number %x\", m)\n\t}\n\tr.version = int(r.b.Range(4, 5)[0])\n\tr.indexVersion = int(r.b.Range(5, 6)[0])\n\n\tr.indexLastPostingEnd = int64(binary.BigEndian.Uint64(r.b.Range(6, headerLen)))\n\n\tif r.version != BinaryFormatV1 {\n\t\treturn errors.Errorf(\"unknown index header file version %d\", r.version)\n\t}\n\n\tr.toc, err = newBinaryTOCFromByteSlice(r.b)\n\tif err != nil {\n\t\treturn errors.Wrap(err, \"read index header TOC\")\n\t}\n","sourceCodeStart":653,"sourceCodeEnd":689,"githubUrl":"https://github.com/thanos-io/thanos/blob/35b8b991177def87ed52dcf10f9b6d87f07282c8/pkg/block/indexheader/binary_reader.go#L653-L689","documentation":"BinaryReader validates the fixed-size header at the start of the binary index-header (magic number, versions, offsets). This error wraps encoding.ErrInvalidSize and is returned when the buffer is shorter than headerLen, i.e., the file does not even contain a complete header — it is empty or truncated.","triggerScenarios":"Loading a binary index-header file/buffer whose total length is less than headerLen: empty cache file created by a failed earlier write, truncated download, or reading a wrong (non-index-header) file.","commonSituations":"A previous WriteBinary crash left a zero-length cache file; partial object-store download; cache path pointing at the wrong file (e.g., the full index instead of the index-header).","solutions":["Delete the truncated/empty cached index-header file and retry — it will be regenerated from the bucket.","If the corrupt header is in the bucket, re-upload the block or its index-header from healthy data.","Confirm the cache path points to a .index-header file, not another file.","Check for disk-full/crash conditions that produced truncated writes."],"exampleFix":"null","handlingStrategy":"fallback","validationCode":"if fi, err := os.Stat(hdrPath); err == nil && fi.Size() < headerLen {\n    os.Remove(hdrPath) // truncated header, force regeneration\n}","typeGuard":"func indexHeaderComplete(path string) bool {\n    fi, err := os.Stat(path)\n    return err == nil && fi.Size() >= headerLen\n}","tryCatchPattern":"r, err := NewBinaryReader(ctx, logger, bkt, dir, id, sampling, metrics)\nif err != nil && errors.Is(err, encoding.ErrInvalidSize) {\n    os.Remove(filepath.Join(dir, id.String()+\".index-header\"))\n    return NewBinaryReader(ctx, logger, bkt, dir, id, sampling, metrics)\n}","preventionTips":["Zero-length/truncated cache files from crashes should be auto-removed.","Check free disk space to avoid truncated writes.","Point the cache at the correct .index-header path, not other files.","Verify object-store objects fully downloaded before caching."],"tags":["truncation","index-header","corruption","validation"],"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"}