{"record":{"id":"1b1179e8f37b4241","repo":"dgraph-io/badger","slug":"while-file-stat-on-file-s-error-v","errorCode":null,"errorMessage":"while file.stat on file: %s, error: %v\n","messagePattern":"while file\\.stat on file: (.+?), error: (.+?)\n","errorType":"exception","errorClass":null,"httpStatus":null,"severity":"error","filePath":"memtable.go","lineNumber":269,"sourceCode":"\tpath string\n\t// This is a lock on the log file. It guards the fd’s value, the file’s\n\t// existence and the file’s memory map.\n\t//\n\t// Use shared ownership when reading/writing the file or memory map, use\n\t// exclusive ownership to open/close the descriptor, unmap or remove the file.\n\tlock     sync.RWMutex\n\tfid      uint32\n\tsize     atomic.Uint32\n\tdataKey  *pb.DataKey\n\tbaseIV   []byte\n\tregistry *KeyRegistry\n\twriteAt  uint32\n\topt      Options\n}\n\nfunc (lf *logFile) Truncate(end int64) error {\n\tif fi, err := lf.Fd.Stat(); err != nil {\n\t\treturn fmt.Errorf(\"while file.stat on file: %s, error: %v\\n\", lf.Fd.Name(), err)\n\t} else if fi.Size() == end {\n\t\treturn nil\n\t}\n\ty.AssertTrue(!lf.opt.ReadOnly)\n\tlf.size.Store(uint32(end))\n\treturn lf.MmapFile.Truncate(end)\n}\n\n// encodeEntry will encode entry to the buf\n// layout of entry\n// +--------+-----+-------+-------+\n// | header | key | value | crc32 |\n// +--------+-----+-------+-------+\nfunc (lf *logFile) encodeEntry(buf *bytes.Buffer, e *Entry, offset uint32) (int, error) {\n\th := header{\n\t\tklen:      uint32(len(e.Key)),\n\t\tvlen:      uint32(len(e.Value)),\n\t\texpiresAt: e.ExpiresAt,","sourceCodeStart":251,"sourceCodeEnd":287,"githubUrl":"https://github.com/dgraph-io/badger/blob/2a001d466f6b71a917319a1db41f99860e16e269/memtable.go#L251-L287","documentation":"logFile.Truncate truncates a memtable WAL to a given end offset. Before truncating it stats the file; if f.Stat fails it returns this error with the filename and underlying OS error. It also asserts the DB is not read-only before proceeding.","triggerScenarios":"Calling Truncate indirectly from UpdateSkipList or doneWriting when the underlying WAL file descriptor is bad (file deleted underneath, fd closed, I/O error, or the DB is read-only so the subsequent truncate would assert anyway).","commonSituations":"File removed by an external cleaner (log rotation, tmpwatch) while badger runs; disk I/O errors; read-only mounts combined with attempts to write; OS-level fd exhaustion leading to bad Stat results.","solutions":["Check the wrapped OS error (%v in the message) to identify why Stat failed (ENOENT, EIO, EBADF)","Stop external file cleaners from touching the badger directory","Verify the volume is writable and healthy (dmesg / fsck); a read-only remount after disk errors is common","Ensure the DB was not opened with ReadOnly:true while writes are expected"],"exampleFix":"// before\nopt := badger.DefaultOptions(dir)\ndb, _ := badger.Open(opt) // opened read-only elsewhere, writes attempted\n// after\nif readOnly {\n    db, err = badger.Open(opt.WithReadOnly(true)) // read path only; no Truncate\n} else {\n    db, err = badger.Open(opt) // writable\n}","handlingStrategy":"try-catch","validationCode":"// ensure the volume is writable and DB not opened read-only when writes/truncates are expected\nif fi, err := os.Stat(dir); err == nil && fi.Mode()&0o200 == 0 {\n    return fmt.Errorf(\"data dir not writable: %s\", dir)\n}","typeGuard":"func isReadOnlyErr(err error) bool {\n    return err != nil && strings.Contains(err.Error(), \"while file.stat on file\")\n}","tryCatchPattern":"if err := runBadger(); err != nil {\n    if strings.Contains(err.Error(), \"while file.stat on file\") {\n        log.Errorf(\"WAL stat failed (deleted under us / I/O error): %v\", err)\n        // restart process on healthy volume after checking dmesg\n    }\n    return err\n}","preventionTips":["Exclude the badger directory from external log-cleaners (logrotate, tmpwatch)","Monitor dmesg/filesystem errors; read-only remounts after disk failures trigger this","Open with WithReadOnly(true) only for genuinely read-only workloads"],"tags":["badger","memtable","io","truncate"],"backgroundTag":"file-stat-failed","analyzedSha":"2a001d466f6b71a917319a1db41f99860e16e269","analyzedAt":"2026-09-05T13:00:02.264Z","contentChangedAt":"2026-09-05T13:00:02.264Z","schemaVersion":2},"datasetVersion":"2026-09-12T17:17:11.597Z"}