{"record":{"id":"6dfefece158ce14f","repo":"thanos-io/thanos","slug":"new-binary-index-header-writer","errorCode":null,"errorMessage":"new binary index header writer","messagePattern":"new binary index header writer","errorType":"error_code","errorClass":null,"httpStatus":null,"severity":"error","filePath":"pkg/block/indexheader/binary_reader.go","lineNumber":129,"sourceCode":"\tif filename != \"\" {\n\t\ttmpDir = filepath.Dir(filename)\n\t}\n\tparallelBucket := WrapWithParallel(bkt, tmpDir)\n\tir, indexVersion, err := newChunkedIndexReader(ctx, parallelBucket, id)\n\tif err != nil {\n\t\treturn nil, errors.Wrap(err, \"new index reader\")\n\t}\n\ttmpFilename := \"\"\n\tif filename != \"\" {\n\t\ttmpFilename = filename + \".tmp\"\n\t}\n\n\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}","sourceCodeStart":111,"sourceCodeEnd":147,"githubUrl":"https://github.com/thanos-io/thanos/blob/35b8b991177def87ed52dcf10f9b6d87f07282c8/pkg/block/indexheader/binary_reader.go#L111-L147","documentation":"Immediately after obtaining the chunked index reader, WriteBinary creates a binary writer (newBinaryWriter) for the tmp index-header file. This error wraps failure to create that writer — usually inability to create or open the tmp file for writing on local disk.","triggerScenarios":"newBinaryWriter(id, tmpFilename, buf) fails during WriteBinary: the directory of `filename` does not exist, filesystem is read-only or full, or permission to create `filename + \".tmp\"` is denied. Also fires when id is empty/invalid and the writer validates it.","commonSituations":"Store gateway configured with a nonexistent or read-only index-header cache directory; volume out of disk space; tmp file left over with bad permissions from a previous crashed run.","solutions":["Ensure the directory containing `filename` (tmpDir) exists and is writable by the process (create it before calling WriteBinary)","Check free disk space and remove stale `<filename>.tmp` files from crashed runs","Fix filesystem permissions or move the cache path to a writable volume","If the cause is an invalid block id, validate id/metadata before calling WriteBinary"],"exampleFix":"// before\nif err := indexheader.WriteBinary(ctx, bkt, id, filename); err != nil {\n\treturn err\n}\n// after\nif err := os.MkdirAll(filepath.Dir(filename), 0o777); err != nil {\n\treturn errors.Wrap(err, \"create index-header dir\")\n}\nif err := indexheader.WriteBinary(ctx, bkt, id, filename); err != nil {\n\treturn errors.Wrap(err, \"write index header\")\n}","handlingStrategy":"validation","validationCode":"dir := filepath.Dir(filename)\nif err := os.MkdirAll(dir, 0o777); err != nil { return err }\nfi, err := os.Stat(dir)\nif err != nil { return err }\nif !fi.IsDir() { return errors.Errorf(\"%s is not a directory\", dir) }\nif err := unix.Access(dir, unix.W_OK); err != nil {\n\treturn errors.Wrapf(err, \"dir %s not writable\", dir)\n}","typeGuard":"func writablePath(filename string) error {\n\tf, err := os.CreateTemp(filepath.Dir(filename), \".wtest\")\n\tif err != nil { return err }\n\tname := f.Name()\n\tf.Close()\n\treturn os.Remove(name)\n}","tryCatchPattern":"if err := indexheader.WriteBinary(ctx, bkt, id, filename); err != nil {\n\tif errors.Is(errors.Cause(err), os.ErrPermission) || errors.Is(errors.Cause(err), syscall.ENOSPC) {\n\t\t// fix permissions/space or fall back to default cache dir, then retry\n\t}\n\treturn errors.Wrapf(err, \"write index header for %s\", id)\n}","preventionTips":["Create and permission the index-header cache directory at startup, not lazily","Monitor disk usage on the store gateway cache volume","Clean up stale .tmp files from crashed writers before restarting","Run the process with a dedicated user owning the cache directory"],"tags":["thanos","indexheader","file-write","filesystem"],"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"}