thanos-io/thanos · error
index header's header
Error message
index header's header
What it means
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.
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.
Example fix
null
Defensive patterns
Strategy: fallback
Validate before calling
if fi, err := os.Stat(hdrPath); err == nil && fi.Size() < headerLen {
os.Remove(hdrPath) // truncated header, force regeneration
} Type guard
func indexHeaderComplete(path string) bool {
fi, err := os.Stat(path)
return err == nil && fi.Size() >= headerLen
} Try / catch
r, err := NewBinaryReader(ctx, logger, bkt, dir, id, sampling, metrics)
if err != nil && errors.Is(err, encoding.ErrInvalidSize) {
os.Remove(filepath.Join(dir, id.String()+".index-header"))
return NewBinaryReader(ctx, logger, bkt, dir, id, sampling, metrics)
} Prevention
- 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.
When it happens
Trigger: 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.
Common situations: 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).
Understand the failure class
Background: "failed to read file", EACCES, ENOENT and "could not read <path>" errors: when a program can't read a file from disk — this error's family across 49 libraries.
Related errors
AI-assisted analysis of thanos-io/thanos@35b8b99117 (2026-09-07).
Data as JSON: /api/errors/86e2a9a33556e27c.
Report an issue: GitHub.
Appendix: source
Thrown at pkg/block/indexheader/binary_reader.go:671
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())
}()
// Verify header.
if r.b.Len() < headerLen {
return errors.Wrap(encoding.ErrInvalidSize, "index header's header")
}
if m := binary.BigEndian.Uint32(r.b.Range(0, 4)); m != MagicIndex {
return errors.Errorf("invalid magic number %x", m)
}
r.version = int(r.b.Range(4, 5)[0])
r.indexVersion = int(r.b.Range(5, 6)[0])
r.indexLastPostingEnd = int64(binary.BigEndian.Uint64(r.b.Range(6, headerLen)))
if r.version != BinaryFormatV1 {
return errors.Errorf("unknown index header file version %d", r.version)
}
r.toc, err = newBinaryTOCFromByteSlice(r.b)
if err != nil {
return errors.Wrap(err, "read index header TOC")
}
View on GitHub (pinned to 35b8b99117)