thanos-io/thanos · error
write index header
Error message
write index header
What it means
When loading an index-header, WriteBinaryToDisk-style logic first tries to read the existing index-header file from disk; if that fails it logs a debug message and regenerates it via WriteBinary (downloading index-header info from the bucket). This error wraps any failure of that regeneration step, so the root cause is inside WriteBinary (bucket download, size-limit error, file creation error, etc.).
Solutions
- Inspect the wrapped (cause) error: if it's a download/object error, verify object-store credentials, endpoint, and that the block's index files exist in the bucket.
- If the cache file was corrupt, delete the cache file and retry — it will be regenerated.
- Check free disk space and permissions on the cache directory.
- Retry the store gateway query; transient bucket errors are often temporary.
Example fix
null
Defensive patterns
Strategy: retry
Validate before calling
// ensure cache dir usable before attempting regeneration
if err := os.MkdirAll(cacheDir, 0o755); err != nil {
return fmt.Errorf("cache dir unusable: %w", err)
}
if fi, err := os.Stat(cachePath); err == nil && fi.Size() == 0 {
os.Remove(cachePath)
} Type guard
null
Try / catch
b, err := WriteBinaryToDisk(ctx, bkt, id, cachePath, metrics.DownloadDuration)
var netErr net.Error
if err != nil && errors.As(err, &netErr) {
return retry.WithBackoff(ctx, func() error {
_, err = WriteBinaryToDisk(ctx, bkt, id, cachePath, metrics.DownloadDuration)
return err
})
} Prevention
- Check object-store credentials and endpoint before load.
- Configure a disk cache so regeneration is rare.
- Monitor bucket error rates and add retry/backoff.
- Delete corrupt cache files promptly instead of blocking.
When it happens
Trigger: NewBinaryReader/LoadBinaryReader path with a cache filename: the cached .index-header file is missing/corrupt on disk, then WriteBinary fails — e.g., bucket download error, object not found, 64GiB size limit hit, or permission failure creating the cache file.
Common situations: Object store outage or wrong credentials causing the index download to fail; corrupted cached index-header being recreated; disk full when writing the regenerated cache file.
Understand the failure class
Background: 'Something went wrong' / 'Request failed (500)' / 'HTTP error! status: 404' — what failed HTTP requests actually mean and how to find the real cause — this error's family across 28 libraries.
Related errors
- generate index header
- invalid magic number
- write index header
- create index header reader
- index header PostingsOffset
AI-assisted analysis of thanos-io/thanos@35b8b99117 (2026-09-07).
Data as JSON: /api/errors/7975998959842730.
Report an issue: GitHub.
Appendix: source
Thrown at pkg/block/indexheader/binary_reader.go:582
postingOffsetsInMemSampling int
metrics *BinaryReaderMetrics
}
// NewBinaryReader loads or builds new index-header if not present on disk.
func NewBinaryReader(ctx context.Context, logger log.Logger, bkt objstore.BucketReader, dir string, id ulid.ULID, postingOffsetsInMemSampling int, metrics *BinaryReaderMetrics) (*BinaryReader, error) {
if dir != "" {
binfn := filepath.Join(dir, id.String(), block.IndexHeaderFilename)
br, err := newFileBinaryReader(binfn, postingOffsetsInMemSampling, metrics)
if err == nil {
return br, nil
}
level.Debug(logger).Log("msg", "failed to read index-header from disk; recreating", "path", binfn, "err", err)
start := time.Now()
if _, err := WriteBinary(ctx, bkt, id, binfn, metrics.downloadDuration); err != nil {
return nil, errors.Wrap(err, "write index header")
}
level.Debug(logger).Log("msg", "built index-header file", "path", binfn, "elapsed", time.Since(start))
return newFileBinaryReader(binfn, postingOffsetsInMemSampling, metrics)
} else {
buf, err := WriteBinary(ctx, bkt, id, "", metrics.downloadDuration)
if err != nil {
return nil, errors.Wrap(err, "generate index header")
}
return newMemoryBinaryReader(buf, postingOffsetsInMemSampling, metrics)
}
}
func newMemoryBinaryReader(buf []byte, postingOffsetsInMemSampling int, metrics *BinaryReaderMetrics) (bw *BinaryReader, err error) {
r := &BinaryReader{
b: realByteSlice(buf),
c: nil,View on GitHub (pinned to 35b8b99117)