{"record":{"id":"4bf1f3099497de0c","repo":"thanos-io/thanos","slug":"read-index-header-toc","errorCode":null,"errorMessage":"read index header TOC","messagePattern":"read index header TOC","errorType":"error_code","errorClass":null,"httpStatus":null,"severity":"error","filePath":"pkg/block/indexheader/binary_reader.go","lineNumber":650,"sourceCode":"\tif err := r.init(); err != nil {\n\t\treturn nil, err\n\t}\n\n\treturn r, nil\n}\n\n// newBinaryTOCFromByteSlice return parsed TOC from given index header byte slice.\nfunc newBinaryTOCFromByteSlice(bs index.ByteSlice) (*BinaryTOC, error) {\n\tif bs.Len() < binaryTOCLen {\n\t\treturn nil, encoding.ErrInvalidSize\n\t}\n\tb := bs.Range(bs.Len()-binaryTOCLen, bs.Len())\n\n\texpCRC := binary.BigEndian.Uint32(b[len(b)-4:])\n\td := encoding.Decbuf{B: b[:len(b)-4]}\n\n\tif d.Crc32(castagnoliTable) != expCRC {\n\t\treturn nil, errors.Wrap(encoding.ErrInvalidChecksum, \"read index header TOC\")\n\t}\n\n\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}()","sourceCodeStart":632,"sourceCodeEnd":668,"githubUrl":"https://github.com/thanos-io/thanos/blob/35b8b991177def87ed52dcf10f9b6d87f07282c8/pkg/block/indexheader/binary_reader.go#L632-L668","documentation":"newBinaryTOCFromByteSlice parses the TOC (table of contents) at the tail of the binary index-header, which ends with a CRC32 (Castagnoli) checksum. This error is returned when the computed checksum does not match the stored one — the wrapped value is encoding.ErrInvalidChecksum — indicating the TOC bytes are corrupted.","triggerScenarios":"Reading a binary index-header whose trailing TOC region fails CRC32 validation: the file was truncated mid-write, corrupted on disk, or copied/tampered with.","commonSituations":"Cache file truncated by a crash or full disk during a previous write; filesystem corruption; manual edits to the .index-header cache file; block uploaded partially to the object store.","solutions":["Delete the cached .index-header file and let the library regenerate it (it does this automatically when the file is unreadable).","Re-download/re-upload the block's index-header if it lives in the object store and is corrupt at the source.","Verify disk health / fsck the cache volume if corruption recurs.","Upgrade Thanos: older versions had cache-write paths vulnerable to truncation."],"exampleFix":"null","handlingStrategy":"fallback","validationCode":"null","typeGuard":"func tocChecksumValid(tocBytes []byte) bool {\n    exp := binary.BigEndian.Uint32(tocBytes[len(tocBytes)-4:])\n    d := encoding.Decbuf{B: tocBytes[:len(tocBytes)-4]}\n    return d.Crc32(castagnoliTable) == exp\n}","tryCatchPattern":"r, err := NewBinaryReader(ctx, logger, bkt, dir, id, sampling, metrics)\nif err != nil && errors.Is(err, encoding.ErrInvalidChecksum) {\n    os.Remove(filepath.Join(dir, id.String()+\".index-header\")) // drop corrupt cache\n    return NewBinaryReader(ctx, logger, bkt, dir, id, sampling, metrics) // regenerate\n}","preventionTips":["Delete cache files that fail checksum instead of failing queries.","Ensure writes are fsynced to avoid torn cache files after crashes.","Monitor disk health on cache volumes.","Verify bucket uploads end-to-end so source headers are not truncated."],"tags":["checksum","corruption","index-header","crc32"],"backgroundTag":"checksum-mismatch","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"}