{"record":{"id":"69c8e318865218b0","repo":"thanos-io/thanos","slug":"flush-69c8e3","errorCode":null,"errorMessage":"flush","messagePattern":"flush","errorType":"error_code","errorClass":null,"httpStatus":null,"severity":"error","filePath":"pkg/block/indexheader/binary_reader.go","lineNumber":142,"sourceCode":"\t// Buffer for copying and encbuffers.\n\t// This also will control the size of file writer buffer.\n\tbuf := make([]byte, 32*1024)\n\tbw, err := newBinaryWriter(id, tmpFilename, buf)\n\tif err != nil {\n\t\treturn nil, errors.Wrap(err, \"new binary index header writer\")\n\t}\n\tdefer runutil.CloseWithErrCapture(&err, bw, \"close binary writer for %s\", tmpFilename)\n\n\tif err := bw.AddIndexMeta(indexVersion, ir.toc.PostingsTable); err != nil {\n\t\treturn nil, errors.Wrap(err, \"add index meta\")\n\t}\n\n\tif err := ir.CopySymbols(bw.SymbolsWriter(), buf); err != nil {\n\t\treturn nil, err\n\t}\n\n\tif err := bw.writer.Flush(); err != nil {\n\t\treturn nil, errors.Wrap(err, \"flush\")\n\t}\n\n\tif err := ir.CopyPostingsOffsets(bw.PostingOffsetsWriter(), buf); err != nil {\n\t\treturn nil, err\n\t}\n\n\tif err := bw.writer.Flush(); err != nil {\n\t\treturn nil, errors.Wrap(err, \"flush\")\n\t}\n\n\tif err := bw.WriteTOC(); err != nil {\n\t\treturn nil, errors.Wrap(err, \"write index header TOC\")\n\t}\n\n\tif err := bw.writer.Flush(); err != nil {\n\t\treturn nil, errors.Wrap(err, \"flush\")\n\t}\n","sourceCodeStart":124,"sourceCodeEnd":160,"githubUrl":"https://github.com/thanos-io/thanos/blob/35b8b991177def87ed52dcf10f9b6d87f07282c8/pkg/block/indexheader/binary_reader.go#L124-L160","documentation":"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.","triggerScenarios":"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).","commonSituations":"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.","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."],"exampleFix":"// before\nif err := bw.writer.Flush(); err != nil {\n    return nil, errors.Wrap(err, \"flush\")\n}\n// after: surface quota/space cause explicitly\nif err := bw.writer.Flush(); err != nil {\n    if st, statErr := os.Stat(filepath.Dir(tmpFilename)); statErr == nil {\n        _ = st\n    }\n    return nil, errors.Wrapf(err, \"flush index-header writer (check disk space on %s)\", filepath.Dir(tmpFilename))\n}","handlingStrategy":"retry","validationCode":"// Go: verify disk has headroom before the flush-heavy build\nfunc hasDiskHeadroom(dir string, minBytes uint64) error {\n    var st syscall.Statfs_t\n    if err := syscall.Statfs(dir, &st); err != nil { return err }\n    if uint64(st.Bavail)*uint64(st.Bsize) < minBytes {\n        return fmt.Errorf(\"less than %d bytes free in %s\", minBytes, dir)\n    }\n    return nil\n}","typeGuard":null,"tryCatchPattern":"// Go\nif err := retry.Do(func() error {\n    _, err := indexheader.WriteBinary(ctx, bkt, id, dst)\n    return err\n}, 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 {\n    return errors.Wrap(err, \"index-header write failed after retries\")\n}","preventionTips":["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."],"tags":["io","filesystem","flush","thanos"],"backgroundTag":"file-write-failed","analyzedSha":"35b8b991177def87ed52dcf10f9b6d87f07282c8","analyzedAt":"2026-09-07T01:49:59.689Z","contentChangedAt":"2026-09-07T01:49:59.689Z","schemaVersion":2},"datasetVersion":"2026-09-15T23:17:13.987Z"}