thanos-io/thanos · warning
close block
Error message
close block
What it means
Wraps b.Close() failure while removing/unloading a block from the BucketStore. The block was found in the loaded map and its metrics decremented, but closing the block's index reader, chunk pool, or temp directory failed. The block directory cleanup is skipped when the block was not downloaded (dir is empty).
Solutions
- Check the wrapped root error: if it is a directory-removal failure, verify the cache/temp directory is writable and mounted.
- Check for file-descriptor or memory pressure that breaks reader Close paths; raise limits or reduce max concurrency.
- Restart the store gateway after the transient condition clears; Close failures are rarely actionable in-process.
Defensive patterns
Strategy: try-catch
Try / catch
if err := store.RemoveBlock(ctx, id); err != nil && strings.Contains(err.Error(), "close block") {
logger.Warn("non-fatal block close failure, will retry next sync", "err", err)
} else if err != nil {
return err
} Prevention
- Raise file-descriptor limits (ulimit) on store gateways.
- Monitor temp/cache directory disk health and free space.
- Allow graceful shutdown periods so in-flight readers can be closed cleanly.
When it happens
Trigger: removeBlock is called during block sync for a block no longer present in the bucket, and BucketBlock.Close returns an error closing the index reader, chunk reader, or on-disk directory.
Common situations: File-descriptor exhaustion preventing readers from closing cleanly, temp-dir on a failing/unmounted disk preventing directory removal, blocks evicted during shutdown while queries still hold readers.
Related errors
- new bucket block
- add block to set
- invalid argument: --min-time
- error while parsing config for request logging
- meta.json not found
AI-assisted analysis of thanos-io/thanos@35b8b99117 (2026-09-07).
Data as JSON: /api/errors/2ad4d2b3d52e6995.
Report an issue: GitHub.
Appendix: source
Thrown at pkg/store/bucket.go:939
}
func (s *BucketStore) removeBlock(id ulid.ULID) error {
s.mtx.Lock()
b, ok := s.blocks[id]
if ok {
lset := labels.FromMap(b.meta.Thanos.Labels)
s.blockSets[lset.Hash()].remove(id)
delete(s.blocks, id)
}
s.mtx.Unlock()
if !ok {
return nil
}
s.metrics.blocksLoaded.Dec()
if err := b.Close(); err != nil {
return errors.Wrap(err, "close block")
}
if b.dir == "" {
return nil
}
return os.RemoveAll(b.dir)
}
// TimeRange returns the minimum and maximum timestamp of data available in the store.
func (s *BucketStore) TimeRange() (mint, maxt int64) {
s.mtx.RLock()
defer s.mtx.RUnlock()
mint = math.MaxInt64
maxt = math.MinInt64
for _, b := range s.blocks {View on GitHub (pinned to 35b8b99117)