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

  1. Delete the cached .index-header file and let the library regenerate it (it does this automatically when the file is unreadable).
  2. Re-download/re-upload the block's index-header if it lives in the object store and is corrupt at the source.
  3. Verify disk health / fsck the cache volume if corruption recurs.
  4. 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

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)