thanos-io/thanos · error
open index reader
Error message
open index reader: %w
What it means
newBlockBaseQuerier opens a TSDB block's index reader via BlockReader.Index() and wraps any failure as 'open index reader: %w'. This happens when the block's index cannot be opened, typically due to corrupted block files, missing index segments, or I/O errors. The wrapped error from the Prometheus tsdb package carries the root cause.
Solutions
- Check the wrapped %w error for the exact cause (e.g. 'invalid magic string', 'file not found')
- Verify the block directory is intact; restore it from object storage or re-replicate the block
- Raise the open-file limit (ulimit -n / systemd LimitNOFILE) if the cause is EMFILE
- Restart/thanos-side repair: remove the corrupt block from local storage and let it be re-fetched
Defensive patterns
Strategy: retry
Validate before calling
if st, err := os.Stat(filepath.Join(blockDir, "index")); err != nil || st.IsDir() { return fmt.Errorf("block index missing: %w", err) } Type guard
func isIndexOpenErr(err error) bool {
return err != nil && strings.Contains(err.Error(), "open index reader")
} Try / catch
q, err := newBlockBaseQuerier(block, mint, maxt)
if err != nil {
var pathErr *os.PathError
if errors.As(err, &pathErr) && errors.Is(pathErr, syscall.EMFILE) { /* raise fd limit / retry later */ }
return err
} Prevention
- Verify block integrity before querying (manifest/checksum in object storage)
- Raise RLIMIT_NOFILE for query-heavy deployments
- Avoid deleting/compacting blocks while readers are open (use tsdb's block lifecycle)
- Monitor disk health and free space on block storage volumes
When it happens
Trigger: newBlockBaseQuerier is invoked by NewCachedBlockChunkQuerier when a cached block querier is created; b.Index() fails for a block being read from disk (corrupt/mismatched index file, block directory incomplete, too many open files).
Common situations: Thanos receive storing blocks locally while a compaction/upload races with a query, disk corruption or partial block download, EMFILE (too many open files) under heavy query load, querying a block directory that was removed mid-query.
Understand the failure class
Background: "open() failed", "failed to open file", "cannot create file" — what a file open error means and how to fix it — this error's family across 42 libraries.
Related errors
AI-assisted analysis of thanos-io/thanos@35b8b99117 (2026-09-07).
Data as JSON: /api/errors/1e77b50ab51eed50.
Report an issue: GitHub.
Appendix: source
Thrown at pkg/receive/expandedpostingscache/tsdb.go:43
This file is basically a copy from https://github.com/prometheus/prometheus/blob/e2e01c1cffbfc4f26f5e9fe6138af87d7ff16122/tsdb/querier.go
with the difference that the PostingsForMatchers function is called from the Postings Cache
*/
type blockBaseQuerier struct {
blockID ulid.ULID
index prom_tsdb.IndexReader
chunks prom_tsdb.ChunkReader
tombstones tombstones.Reader
closed bool
mint, maxt int64
}
func newBlockBaseQuerier(b prom_tsdb.BlockReader, mint, maxt int64) (*blockBaseQuerier, error) {
indexr, err := b.Index()
if err != nil {
return nil, fmt.Errorf("open index reader: %w", err)
}
chunkr, err := b.Chunks()
if err != nil {
indexr.Close()
return nil, fmt.Errorf("open chunk reader: %w", err)
}
tombsr, err := b.Tombstones()
if err != nil {
indexr.Close()
chunkr.Close()
return nil, fmt.Errorf("open tombstone reader: %w", err)
}
if tombsr == nil {
tombsr = tombstones.NewMemTombstones()
}
return &blockBaseQuerier{
blockID: b.Meta().ULID,View on GitHub (pinned to 35b8b99117)