thanos-io/thanos · error
open index writer
Error message
open index writer
What it means
NewDiskWriter fails when index.NewWriter cannot create the index writer for the temporary block's index file. Without an index the block is unusable, so creation aborts right after the chunk writer was opened.
Solutions
- Check free disk space — index writing needs headroom after chunks.
- Verify write permissions on the block temp directory.
- Ensure no leftover file exists at <bTmp>/index blocking the new writer.
- Pass a live (non-cancelled) context to NewDiskWriter.
Example fix
// before d, err := NewDiskWriter(ctx, cancelledCtx, bdir) // ctx already cancelled // after d, err := NewDiskWriter(ctx, context.Background(), bdir)
Defensive patterns
Strategy: try-catch
Validate before calling
if err := ctx.Err(); err != nil {
return fmt.Errorf("context cancelled before block write: %w", err)
}
if free, err := diskFree(bdir); err == nil && free < minRequiredBytes {
return fmt.Errorf("insufficient disk space: %d bytes free", free)
} Try / catch
d, err := block.NewDiskWriter(ctx, bdir, logger)
if err != nil {
if strings.Contains(err.Error(), "open index writer") {
return fmt.Errorf("cannot create index writer (disk space/ctx?): %w", err)
}
return err
} Prevention
- Monitor free disk space; index writes need headroom after chunks.
- Always pass a live context to NewDiskWriter and keep it alive through Flush.
- Remove leftover 'index' files from interrupted tmp dirs.
When it happens
Trigger: index.NewWriter(ctx, <bTmp>/index) failing due to OS-level open/creation errors: permission denied, disk full, path conflicts, or invalid context already cancelled.
Common situations: Disk full after chunk writing consumed space; write permissions removed mid-write; a stale regular file at the index path blocking creation; context cancelled before writer setup.
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
- open chunk writer
- open temporary block dir
- sync temporary dir file
- close temporary dir
- replace index file
AI-assisted analysis of thanos-io/thanos@35b8b99117 (2026-09-07).
Data as JSON: /api/errors/72f3b809f00070ee.
Report an issue: GitHub.
Appendix: source
Thrown at pkg/block/writer.go:96
if err = os.RemoveAll(bTmp); err != nil {
return nil, err
}
if err = os.MkdirAll(bTmp, 0750); err != nil {
return nil, err
}
chunkw, err := chunks.NewWriter(filepath.Join(bTmp, ChunksDirname))
if err != nil {
return nil, errors.Wrap(err, "open chunk writer")
}
d.closers = append(d.closers, chunkw)
// TODO(bwplotka): Setup instrumentedChunkWriter if we want to upstream this code.
indexw, err := index.NewWriter(ctx, filepath.Join(bTmp, IndexFilename))
if err != nil {
return nil, errors.Wrap(err, "open index writer")
}
d.closers = append(d.closers, indexw)
d.statsGatheringSeriesWriter = statsGatheringSeriesWriter{iw: indexw, cw: chunkw}
return d, nil
}
func (d *DiskWriter) Flush() (_ tsdb.BlockStats, err error) {
defer func() {
if err != nil {
err = tsdb_errors.NewMulti(err, tsdb_errors.CloseAll(d.closers)).Err()
if err := os.RemoveAll(d.bTmp); err != nil {
level.Error(d.logger).Log("msg", "removed tmp folder failed after block(s) write", "err", err.Error())
}
}
}()
df, err := fileutil.OpenDir(d.bTmp)
if err != nil {
return tsdb.BlockStats{}, errors.Wrap(err, "open temporary block dir")View on GitHub (pinned to 35b8b99117)