thanos-io/thanos · error
flush
Error message
flush
What it means
After copying symbols into the binary writer, WriteBinary flushes the bufio.Writer (bw.writer.Flush()) to push all buffered bytes into the underlying output (file or in-memory buffer). This error wraps a flush failure right after CopySymbols — i.e. writing the accumulated index-meta plus symbol data to the backing file failed.
Solutions
- Check disk space and inode availability on the target filesystem (df -h, df -i).
- Confirm the volume is writable and not remounted read-only (mount | grep <path>).
- Check filesystem/device errors in dmesg and repair or replace failing storage.
- Retry the operation; for block bucket-backed flows, deleting a partial <index-header>.tmp and re-running WriteBinary is safe.
Example fix
// before
if err := bw.writer.Flush(); err != nil {
return nil, errors.Wrap(err, "flush")
}
// after: surface quota/space cause explicitly
if err := bw.writer.Flush(); err != nil {
if st, statErr := os.Stat(filepath.Dir(tmpFilename)); statErr == nil {
_ = st
}
return nil, errors.Wrapf(err, "flush index-header writer (check disk space on %s)", filepath.Dir(tmpFilename))
} Defensive patterns
Strategy: retry
Validate before calling
// Go: verify disk has headroom before the flush-heavy build
func hasDiskHeadroom(dir string, minBytes uint64) error {
var st syscall.Statfs_t
if err := syscall.Statfs(dir, &st); err != nil { return err }
if uint64(st.Bavail)*uint64(st.Bsize) < minBytes {
return fmt.Errorf("less than %d bytes free in %s", minBytes, dir)
}
return nil
} Try / catch
// Go
if err := retry.Do(func() error {
_, err := indexheader.WriteBinary(ctx, bkt, id, dst)
return err
}, retry.OnRetry(func(n uint, err error) { log.Warn("retrying index-header write after flush failure", "attempt", n, "err", err) }), retry.Attempts(3)); err != nil {
return errors.Wrap(err, "index-header write failed after retries")
} Prevention
- Set disk-usage alerts on the block data volume (flush failures cluster near 100% full).
- Avoid network filesystems for local index-header caching; use local SSD.
- In Kubernetes, set ephemeral-storage requests/limits high enough for block index-headers.
- Log the wrapped cause (errors.Cause) to distinguish ENOSPC from EIO.
When it happens
Trigger: WriteBinary -> bw.writer.Flush() returning a non-nil error after symbol copy: the underlying os.File write failed (disk full, EIO), or the file was closed/invalid. Triggered by any caller of WriteBinary (NewBinaryReader, NewLazyBinaryReader, benchmarks, tests).
Common situations: Disk-quota exceeded on store-gateway/compactor data volume; filesystem remounted read-only; NFS/ObjectStorage-mounted volume with intermittent I/O errors while materializing the index-header.
Understand the failure class
Background: "failed to write file", "Could not save figure", "Error saving remote file" — file write failed: causes and fixes across languages and libraries — this error's family across 38 libraries.
Related errors
AI-assisted analysis of thanos-io/thanos@35b8b99117 (2026-09-07).
Data as JSON: /api/errors/69c8e318865218b0.
Report an issue: GitHub.
Appendix: source
Thrown at pkg/block/indexheader/binary_reader.go:142
// Buffer for copying and encbuffers.
// This also will control the size of file writer buffer.
buf := make([]byte, 32*1024)
bw, err := newBinaryWriter(id, tmpFilename, buf)
if err != nil {
return nil, errors.Wrap(err, "new binary index header writer")
}
defer runutil.CloseWithErrCapture(&err, bw, "close binary writer for %s", tmpFilename)
if err := bw.AddIndexMeta(indexVersion, ir.toc.PostingsTable); err != nil {
return nil, errors.Wrap(err, "add index meta")
}
if err := ir.CopySymbols(bw.SymbolsWriter(), buf); err != nil {
return nil, err
}
if err := bw.writer.Flush(); err != nil {
return nil, errors.Wrap(err, "flush")
}
if err := ir.CopyPostingsOffsets(bw.PostingOffsetsWriter(), buf); err != nil {
return nil, err
}
if err := bw.writer.Flush(); err != nil {
return nil, errors.Wrap(err, "flush")
}
if err := bw.WriteTOC(); err != nil {
return nil, errors.Wrap(err, "write index header TOC")
}
if err := bw.writer.Flush(); err != nil {
return nil, errors.Wrap(err, "flush")
}
View on GitHub (pinned to 35b8b99117)