thanos-io/thanos · critical
open index
Error message
open index
What it means
block.Repair wraps the error returned by b.Index(), which opens a read handle over the block's index file after the block was successfully opened. Failure means the index file exists but cannot be read/parsed into an index reader — typically decoding errors from corruption. Wrapped as 'open index: <cause>'.
Solutions
- Read the wrapped cause; if it indicates index decoding corruption, verify with `thanos tools bucket verify` on the bucket or a local index inspection.
- Re-fetch the block from object storage and compare checksums; retry Repair on the intact copy.
- If no intact copy exists, delete the block and regenerate data from the source Prometheus (re-upload or re-compact).
- Keep Repair as a last resort: prefer preventing issue-347 corruption by upgrading Prometheus past the bug.
Example fix
// before
_, err = block.RepairIssue347(ctx, logger, dir, id, source)
// treat as transient and retry forever
// after
_, err = block.RepairIssue347(ctx, logger, dir, id, source)
if err != nil && strings.Contains(err.Error(), "open index") {
// index unreadable: re-download block once, then fail permanently
if derr := redownloadBlock(ctx, bucket, dir, id); derr != nil {
return derr
}
_, err = block.RepairIssue347(ctx, logger, dir, id, source)
} Defensive patterns
Strategy: try-catch
Try / catch
resid, err := block.RepairIssue347(ctx, logger, dir, id, source)
if err != nil && strings.Contains(err.Error(), "open index") {
// index unreadable: quarantine the block instead of retrying
if qerr := quarantineBlock(dir, id); qerr != nil {
return resid, qerr
}
return resid, fmt.Errorf("block %s quarantined: index unreadable", id)
} Prevention
- Upgrade Prometheus/Thanos past the tsdb#347 bug so corrupt indexes are not produced.
- Run `thanos tools bucket verify` periodically to catch unreadable indexes early.
- Alert on repair failures containing 'open index' — they indicate non-self-healing corruption.
- Keep block replicas in object storage so an unreadable index can be restored.
When it happens
Trigger: Repair on a block whose index file is corrupt (e.g. the tsdb issue-347 out-of-order-chunk corruption that Repair targets), truncated during transfer, or whose TOC/symbols sections are damaged; disk read errors mid-open.
Common situations: Blocks affected by the Prometheus tsdb#347 bug where the index is malformed enough that even opening a reader fails; blocks uploaded while Prometheus was still writing them (rare, but seen with unsafe tooling); partial restore from backup.
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/03fa8375c90cdd31.
Report an issue: GitHub.
Appendix: source
Thrown at pkg/block/index.go:440
resid = ulid.MustNew(ulid.Now(), entropy)
meta, err := metadata.ReadFromDir(bdir)
if err != nil {
return resid, errors.Wrap(err, "read meta file")
}
if meta.Thanos.Downsample.Resolution > 0 {
return resid, errors.New("cannot repair downsampled block")
}
b, err := tsdb.OpenBlock(logutil.GoKitLogToSlog(logger), bdir, nil, nil)
if err != nil {
return resid, errors.Wrap(err, "open block")
}
defer runutil.CloseWithErrCapture(&err, b, "repair block reader")
indexr, err := b.Index()
if err != nil {
return resid, errors.Wrap(err, "open index")
}
defer runutil.CloseWithErrCapture(&err, indexr, "repair index reader")
chunkr, err := b.Chunks()
if err != nil {
return resid, errors.Wrap(err, "open chunks")
}
defer runutil.CloseWithErrCapture(&err, chunkr, "repair chunk reader")
resdir := filepath.Join(dir, resid.String())
chunkw, err := chunks.NewWriter(filepath.Join(resdir, ChunksDirname))
if err != nil {
return resid, errors.Wrap(err, "open chunk writer")
}
defer runutil.CloseWithErrCapture(&err, chunkw, "repair chunk writer")
indexw, err := index.NewWriter(context.TODO(), filepath.Join(resdir, IndexFilename))View on GitHub (pinned to 35b8b99117)