benbjohnson/litestream · error
write page %d: %w
Error message
write page %d: %w
What it means
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.
Source
Thrown at replica.go:981
defer internal.UnlockFile(f)
for {
var phdr ltx.PageHeader
data := make([]byte, pageSize)
if err := dec.DecodePage(&phdr, data); err == io.EOF {
break
} else if err != nil {
return fmt.Errorf("decode page: %w", err)
}
if phdr.Pgno == 1 && len(data) >= 28 {
data[18], data[19] = 0x01, 0x01
_, _ = rand.Read(data[24:28])
}
off := int64(phdr.Pgno-1) * int64(pageSize)
if _, err := f.WriteAt(data, off); err != nil {
return fmt.Errorf("write page %d: %w", phdr.Pgno, err)
}
}
if hdr.Commit > 0 {
if err := f.Sync(); err != nil {
return fmt.Errorf("sync before truncate: %w", err)
}
newSize := int64(hdr.Commit) * int64(pageSize)
if err := f.Truncate(newSize); err != nil {
return fmt.Errorf("truncate: %w", err)
}
}
if err := dec.Close(); err != nil {
return fmt.Errorf("close decoder: %w", err)
}
return f.Sync()View on GitHub (pinned to 4ed7a308f6)
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
Example fix
# before df -h /var/lib/db # disk 100% full # after fstrim /var/lib/db && df -h /var/lib/db # space freed, retry apply
Defensive patterns
Strategy: validation
Validate before calling
stat := syscall.Statfs_t{}
if err := syscall.Statfs(filepath.Dir(dbPath), &stat); err == nil {
avail := stat.Bavail * uint64(stat.Bsize)
if avail < 2*uint64(dbSizeHint) {
return fmt.Errorf("insufficient disk space: %d bytes free", avail)
}
}
if f, err := os.OpenFile(dbPath, os.O_WRONLY, 0); err != nil {
return fmt.Errorf("db not writable: %w", err)
} else { f.Close() } Try / catch
if err := r.applyLTXFile(ctx, f, info, pageSize); err != nil {
if errors.Is(err, syscall.ENOSPC) || errors.Is(err, syscall.EIO) {
// disk-full / IO: page ops team, do not blind-retry
return fmt.Errorf("storage failure applying %s: %w", info.Path(), err)
}
return err
} Prevention
- 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)
When it happens
Trigger: 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.
Common situations: 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.
Understand the failure class
Background: "failed to write file", "Could not save figure", "Error saving remote file" — file write failed: causes and fixes across languages and libraries — this error's family across 38 libraries.
Related errors
- disk full
- failed to scan directory %s: %w
- cannot remove tmp files: %w
- create temp L0 file: %w
- sync L0 file: %w
AI-assisted analysis of benbjohnson/litestream@4ed7a308f6 (2026-09-06).
Data as JSON: /api/errors/f45581783a3a32ff.
Report an issue: GitHub.