thanos-io/thanos · error

open chunk reader

Error message

open chunk reader: %w

What it means

newBlockBaseQuerier opens the block's chunk reader via BlockReader.Chunks() and wraps failure as 'open chunk reader: %w'; it first closes the already-opened index reader to avoid leaks. Chunk reader failures usually indicate corrupted or missing chunk segment files in the block directory.

Solutions

  1. Inspect the wrapped %w error to identify the failing chunk segment
  2. Restore or re-download the affected block from object storage; delete the local corrupt copy
  3. Check disk space and filesystem health (dmesg, df) on the storage volume
  4. Increase file-descriptor limits if the cause is resource exhaustion
Defensive patterns

Strategy: retry

Validate before calling

segs, err := filepath.Glob(filepath.Join(blockDir, "chunks", "*"))
if err != nil || len(segs) == 0 { return errors.New("block has no chunk segments") }

Type guard

func isChunkOpenErr(err error) bool {
    return err != nil && strings.Contains(err.Error(), "open chunk reader")
}

Try / catch

q, err := newBlockBaseQuerier(block, mint, maxt)
if err != nil && strings.Contains(err.Error(), "open chunk reader") {
    // re-fetch or re-download the block, then retry once
}

Prevention

When it happens

Trigger: NewCachedBlockChunkQuerier -> newBlockBaseQuerier; b.Chunks() returns an error (missing chunk segments, truncated chunk file, checksum mismatch) after the index reader opened successfully.

Common situations: Disk full or disk corruption on the receive store path, block deleted/compacted concurrently while a query opened it, partial block restore, too many open files.

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/7f8cc81339f4874b. Report an issue: GitHub.

Appendix: source

Thrown at pkg/receive/expandedpostingscache/tsdb.go:48

	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,
		mint:       mint,
		maxt:       maxt,
		index:      indexr,
		chunks:     chunkr,
		tombstones: tombsr,

View on GitHub (pinned to 35b8b99117)