thanos-io/thanos · error
open block
Error message
open block %s
What it means
processDownsampling wraps tsdb.OpenBlock failures as errors.Wrapf(err, "open block %s", m.ULID). The downloaded block directory cannot be opened as a TSDB block — typically missing/corrupt index, chunks, or meta.json files on local disk.
Solutions
- Clear the block's directory under --data-dir and let the next cycle re-download it (local cache is safe to delete).
- Check disk health and that no cleaner process removes files from --data-dir while downsampling runs.
- Raise the process file-descriptor limit (ulimit -n) if errors indicate too many open files.
- If the source block in the bucket is itself broken, remove it after verification so retries stop.
Defensive patterns
Strategy: fallback
Validate before calling
// validate local copy before opening
for _, f := range []string{"meta.json", "index"} {
if _, err := os.Stat(filepath.Join(bdir, f)); err != nil {
os.RemoveAll(bdir) // force re-download
}
} Try / catch
b, err := tsdb.OpenBlock(logger, bdir, pool, nil)
if err != nil {
os.RemoveAll(bdir) // clear local cache and retry next cycle
return fmt.Errorf("open block %s: %w", m.ULID, err)
} Prevention
- Treat --data-dir as an always-deletable cache; automate cleanup of stale block dirs.
- Raise RLIMIT_NOFILE for the downsampler process.
- Monitor disk health and avoid unclean shutdowns of nodes running downsamplers.
When it happens
Trigger: tsdb.OpenBlock(bdir, pool, nil) fails because index file is unreadable/corrupt, chunk files are missing, meta.json is invalid, or the block directory was deleted mid-operation.
Common situations: Incomplete download that passed earlier checks but is missing chunk segments; disk corruption or cleanup daemon removing files from --data-dir; running out of file descriptors; checksum-identical but truncated files after a crash.
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/fce22d6cc0b83f9d.
Report an issue: GitHub.
Appendix: source
Thrown at cmd/thanos/downsample.go:381
}
level.Info(logger).Log("msg", "downloaded block", "id", m.ULID, "duration", time.Since(begin), "duration_ms", time.Since(begin).Milliseconds())
if err := block.VerifyIndex(ctx, logger, filepath.Join(bdir, block.IndexFilename), m.MinTime, m.MaxTime); err != nil && !acceptMalformedIndex {
return errors.Wrap(err, "input block index not valid")
}
begin = time.Now()
var pool chunkenc.Pool
if m.Thanos.Downsample.Resolution == 0 {
pool = chunkenc.NewPool()
} else {
pool = downsample.NewPool()
}
b, err := tsdb.OpenBlock(logutil.GoKitLogToSlog(logger), bdir, pool, nil)
if err != nil {
return errors.Wrapf(err, "open block %s", m.ULID)
}
defer runutil.CloseWithLogOnErr(log.With(logger, "outcome", "potential left mmap file handlers left"), b, "tsdb reader")
id, err := downsample.Downsample(ctx, logger, m, b, dir, resolution)
if err != nil {
return errors.Wrapf(err, "downsample block %s to window %d", m.ULID, resolution)
}
resdir := filepath.Join(dir, id.String())
downsampleDuration := time.Since(begin)
level.Info(logger).Log("msg", "downsampled block",
"from", m.ULID, "to", id, "duration", downsampleDuration, "duration_ms", downsampleDuration.Milliseconds())
metrics.downsampleDuration.WithLabelValues(m.Thanos.ResolutionString()).Observe(downsampleDuration.Seconds())
stats, err := block.GatherIndexHealthStats(ctx, logger, filepath.Join(resdir, block.IndexFilename), m.MinTime, m.MaxTime)
if err == nil {
err = stats.AnyErr()
}View on GitHub (pinned to 35b8b99117)