{"record":{"id":"f45581783a3a32ff","repo":"benbjohnson/litestream","slug":"write-page-d-w","errorCode":null,"errorMessage":"write page %d: %w","messagePattern":"write page (.+?): %w","errorType":"exception","errorClass":null,"httpStatus":null,"severity":"error","filePath":"replica.go","lineNumber":981,"sourceCode":"\tdefer internal.UnlockFile(f)\n\n\tfor {\n\t\tvar phdr ltx.PageHeader\n\t\tdata := make([]byte, pageSize)\n\t\tif err := dec.DecodePage(&phdr, data); err == io.EOF {\n\t\t\tbreak\n\t\t} else if err != nil {\n\t\t\treturn fmt.Errorf(\"decode page: %w\", err)\n\t\t}\n\n\t\tif phdr.Pgno == 1 && len(data) >= 28 {\n\t\t\tdata[18], data[19] = 0x01, 0x01\n\t\t\t_, _ = rand.Read(data[24:28])\n\t\t}\n\n\t\toff := int64(phdr.Pgno-1) * int64(pageSize)\n\t\tif _, err := f.WriteAt(data, off); err != nil {\n\t\t\treturn fmt.Errorf(\"write page %d: %w\", phdr.Pgno, err)\n\t\t}\n\t}\n\n\tif hdr.Commit > 0 {\n\t\tif err := f.Sync(); err != nil {\n\t\t\treturn fmt.Errorf(\"sync before truncate: %w\", err)\n\t\t}\n\t\tnewSize := int64(hdr.Commit) * int64(pageSize)\n\t\tif err := f.Truncate(newSize); err != nil {\n\t\t\treturn fmt.Errorf(\"truncate: %w\", err)\n\t\t}\n\t}\n\n\tif err := dec.Close(); err != nil {\n\t\treturn fmt.Errorf(\"close decoder: %w\", err)\n\t}\n\n\treturn f.Sync()","sourceCodeStart":963,"sourceCodeEnd":999,"githubUrl":"https://github.com/benbjohnson/litestream/blob/4ed7a308f6271ebfd2b0a6e4b70b03011a37e4a3/replica.go#L963-L999","documentation":"applyLTXFile failed to write a decoded page into the local database file at the offset derived from the page number ((Pgno-1)*pageSize). This is a low-level file write failure (WriteAt) while reconstructing the database from the LTX transaction, and it aborts page application immediately to avoid a torn database.","triggerScenarios":"os.File.WriteAt fails for page phdr.Pgno: disk full, I/O error on the database volume, file descriptor/permission problems on the DB path, or a write offset beyond filesystem limits.","commonSituations":"Disk full on the host holding the SQLite database, failing or read-only-remounted volumes, Docker/Kubernetes volume exhaustion, NFS/EFS transient I/O errors during restore.","solutions":["Free disk space on the volume containing the database file","Check filesystem/volume health (dmesg, fsck) and remount read-write if needed","Verify the litestream process has write permission to the database path","Retry the replication/restore after resolving the I/O condition"],"exampleFix":"# before\ndf -h /var/lib/db   # disk 100% full\n# after\nfstrim /var/lib/db && df -h /var/lib/db   # space freed, retry apply","handlingStrategy":"validation","validationCode":"stat := syscall.Statfs_t{}\nif err := syscall.Statfs(filepath.Dir(dbPath), &stat); err == nil {\n    avail := stat.Bavail * uint64(stat.Bsize)\n    if avail < 2*uint64(dbSizeHint) {\n        return fmt.Errorf(\"insufficient disk space: %d bytes free\", avail)\n    }\n}\nif f, err := os.OpenFile(dbPath, os.O_WRONLY, 0); err != nil {\n    return fmt.Errorf(\"db not writable: %w\", err)\n} else { f.Close() }","typeGuard":null,"tryCatchPattern":"if err := r.applyLTXFile(ctx, f, info, pageSize); err != nil {\n    if errors.Is(err, syscall.ENOSPC) || errors.Is(err, syscall.EIO) {\n        // disk-full / IO: page ops team, do not blind-retry\n        return fmt.Errorf(\"storage failure applying %s: %w\", info.Path(), err)\n    }\n    return err\n}","preventionTips":["Alert on disk usage thresholds for the volume holding the database","Run litestream with a user that owns the database file","Use local disks or reliable block storage, not flaky network mounts","Set up filesystem health monitoring (SMART, dmesg watchers)"],"tags":["filesystem","disk-full","io","replication"],"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"}