thanos-io/thanos · error
read index header TOC
Error message
read index header TOC
What it means
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.
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.
Example fix
null
Defensive patterns
Strategy: fallback
Validate before calling
null
Type guard
func tocChecksumValid(tocBytes []byte) bool {
exp := binary.BigEndian.Uint32(tocBytes[len(tocBytes)-4:])
d := encoding.Decbuf{B: tocBytes[:len(tocBytes)-4]}
return d.Crc32(castagnoliTable) == exp
} Try / catch
r, err := NewBinaryReader(ctx, logger, bkt, dir, id, sampling, metrics)
if err != nil && errors.Is(err, encoding.ErrInvalidChecksum) {
os.Remove(filepath.Join(dir, id.String()+".index-header")) // drop corrupt cache
return NewBinaryReader(ctx, logger, bkt, dir, id, sampling, metrics) // regenerate
} Prevention
- 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.
When it happens
Trigger: 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.
Common situations: 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.
Understand the failure class
Background: Checksum mismatch errors: "checksum verification failed", "digest mismatch", "expected vs actual checksum" — what they mean and how to fix them — this error's family across 41 libraries.
Related errors
AI-assisted analysis of thanos-io/thanos@35b8b99117 (2026-09-07).
Data as JSON: /api/errors/4bf1f3099497de0c.
Report an issue: GitHub.
Appendix: source
Thrown at pkg/block/indexheader/binary_reader.go:650
if err := r.init(); err != nil {
return nil, err
}
return r, nil
}
// newBinaryTOCFromByteSlice return parsed TOC from given index header byte slice.
func newBinaryTOCFromByteSlice(bs index.ByteSlice) (*BinaryTOC, error) {
if bs.Len() < binaryTOCLen {
return nil, encoding.ErrInvalidSize
}
b := bs.Range(bs.Len()-binaryTOCLen, bs.Len())
expCRC := binary.BigEndian.Uint32(b[len(b)-4:])
d := encoding.Decbuf{B: b[:len(b)-4]}
if d.Crc32(castagnoliTable) != expCRC {
return nil, errors.Wrap(encoding.ErrInvalidChecksum, "read index header TOC")
}
if err := d.Err(); err != nil {
return nil, err
}
return &BinaryTOC{
Symbols: d.Be64(),
PostingsOffsetTable: d.Be64(),
}, nil
}
func (r *BinaryReader) init() (err error) {
start := time.Now()
defer func() {
r.metrics.loadDuration.Observe(time.Since(start).Seconds())
}()View on GitHub (pinned to 35b8b99117)