{"record":{"id":"f14a04781a22c5ff","repo":"benbjohnson/litestream","slug":"create-temp-l0-file-w","errorCode":null,"errorMessage":"create temp L0 file: %w","messagePattern":"create temp L0 file: %w","errorType":"exception","errorClass":null,"httpStatus":null,"severity":"error","filePath":"db.go","lineNumber":1637,"sourceCode":"\tif err := internal.MkdirAll(l0Dir, db.dirInfo); err != nil {\n\t\treturn fmt.Errorf(\"recreate L0 directory: %w\", err)\n\t}\n\n\t// Fetch latest L0 LTX file from replica\n\tminTXID, maxTXID := replicaInfo.MinTXID, replicaInfo.MaxTXID\n\treader, err := db.Replica.Client.OpenLTXFile(ctx, 0, minTXID, maxTXID, 0, 0)\n\tif err != nil {\n\t\treturn fmt.Errorf(\"open remote L0 file: %w\", err)\n\t}\n\tdefer func() { _ = reader.Close() }()\n\n\t// Write to temp file and atomically rename\n\tlocalPath := db.LTXPath(0, minTXID, maxTXID)\n\ttmpPath := localPath + \".tmp\"\n\n\ttmpFile, err := os.Create(tmpPath)\n\tif err != nil {\n\t\treturn fmt.Errorf(\"create temp L0 file: %w\", err)\n\t}\n\tdefer func() { _ = os.Remove(tmpPath) }() // Clean up temp file on error\n\n\tif _, err := io.Copy(tmpFile, reader); err != nil {\n\t\t_ = tmpFile.Close()\n\t\treturn fmt.Errorf(\"copy L0 file: %w\", err)\n\t}\n\n\tif err := tmpFile.Sync(); err != nil {\n\t\t_ = tmpFile.Close()\n\t\treturn fmt.Errorf(\"sync L0 file: %w\", err)\n\t}\n\n\tif err := tmpFile.Close(); err != nil {\n\t\treturn fmt.Errorf(\"close L0 file: %w\", err)\n\t}\n\n\t// Atomically rename temp file to final path","sourceCodeStart":1619,"sourceCodeEnd":1655,"githubUrl":"https://github.com/benbjohnson/litestream/blob/4ed7a308f6271ebfd2b0a6e4b70b03011a37e4a3/db.go#L1619-L1655","documentation":"The fetched remote L0 LTX file is first written to a temp file (localPath + \".tmp\"). This error wraps os.Create failing on that temp path, meaning Litestream could not create the staging file in the L0 directory.","triggerScenarios":"checkDatabaseBehindReplica calls os.Create(tmpPath) after successfully opening the remote reader, and creation fails — L0 directory not writable, disk full, or a stale .tmp file with bad permissions exists from a previous crash.","commonSituations":"Disk-full on the volume holding the LTX directory; leftover .tmp file owned by root from an earlier run as a different user; read-only mount; tmpwatch/logrotate-like cleaners interfering in the LTX directory.","solutions":["Check free disk space (df -h) and expand the volume if full.","Remove stale *.tmp files in the L0 dir and fix their ownership (rm .../*.tmp; chown -R litestream ...).","Verify the litestream process user has write permission on the L0 directory.","Inspect the wrapped OS error for the exact path and errno."],"exampleFix":"// before: stale tmp file owned by root blocks os.Create\n$ ls -l /var/lib/db/ltx/0/*.tmp  # root:root\n// after: clean and fix ownership\n$ rm /var/lib/db/ltx/0/*.tmp && chown -R litestream:litestream /var/lib/db","handlingStrategy":"validation","validationCode":"// Probe disk space and writability of the LTX dir\nst, err := os.Statfs(l0Dir)\nif err == nil && st.Bavail*uint64(st.Bsize) < 64*1024*1024 {\n    log.Printf(\"low disk: %d bytes free\", st.Bavail*uint64(st.Bsize))\n}","typeGuard":"null","tryCatchPattern":"tmpFile, err := os.Create(tmpPath)\nif err != nil {\n    return fmt.Errorf(\"create temp L0 file: %w\", err)\n}\ndefer os.Remove(tmpPath) // clean stale tmp on failure","preventionTips":["Alert on disk usage above ~80% on the data volume","Remove stale *.tmp files owned by wrong users after user changes","Keep external file cleaners away from the ltx/ tree","Run all litestream invocations as the same user"],"tags":["litestream","filesystem","temp-file","disk-full","l0"],"backgroundTag":"file-write-failed","analyzedSha":"4ed7a308f6271ebfd2b0a6e4b70b03011a37e4a3","analyzedAt":"2026-09-06T18:29:25.564Z","contentChangedAt":"2026-09-06T18:29:25.564Z","schemaVersion":2},"datasetVersion":"2026-09-14T05:17:10.506Z"}