benbjohnson/litestream · error
sync L0 file: %w
Error message
sync L0 file: %w
What it means
After copying, the temp file is flushed to disk with tmpFile.Sync() before rename. This error wraps a failure of fsync on the temp L0 file, meaning the fetched LTX data could not be durably committed to storage and the file is abandoned.
Source
Thrown at db.go:1648
// Write to temp file and atomically rename
localPath := db.LTXPath(0, minTXID, maxTXID)
tmpPath := localPath + ".tmp"
tmpFile, err := os.Create(tmpPath)
if err != nil {
return fmt.Errorf("create temp L0 file: %w", err)
}
defer func() { _ = os.Remove(tmpPath) }() // Clean up temp file on error
if _, err := io.Copy(tmpFile, reader); err != nil {
_ = tmpFile.Close()
return fmt.Errorf("copy L0 file: %w", err)
}
if err := tmpFile.Sync(); err != nil {
_ = tmpFile.Close()
return fmt.Errorf("sync L0 file: %w", err)
}
if err := tmpFile.Close(); err != nil {
return fmt.Errorf("close L0 file: %w", err)
}
// Atomically rename temp file to final path
if err := os.Rename(tmpPath, localPath); err != nil {
return fmt.Errorf("rename L0 file: %w", err)
}
db.invalidatePosCache()
db.Logger.Info("fetched latest L0 file from replica",
"min_txid", minTXID,
"max_txid", maxTXID)
return nil
}View on GitHub (pinned to 4ed7a308f6)
Solutions
- Free disk space (df -h) — ENOSPC at fsync time is common even when create/copy succeeded.
- Check dmesg/smart data for device I/O errors on the data volume.
- If running in a container, verify the storage driver supports reliable fsync (avoid tmpfs for the LTX dir).
- Retry after fixing the disk; the .tmp file is cleaned up automatically on error.
Example fix
// before: data volume at 100% $ df -h /var/lib/db # 100% used // after: free space or grow volume before restarting litestream $ systemctl stop litestream && rm -f /var/lib/db/*.tmp && systemctl start litestream
Defensive patterns
Strategy: try-catch
Validate before calling
// Keep headroom: fail early if disk is nearly full
st, _ := os.Statfs(dataDir)
if st.Bavail*uint64(st.Bsize) < 128*1024*1024 {
log.Printf("refusing fetch, low disk")
} Type guard
null
Try / catch
if err := tmpFile.Sync(); err != nil {
_ = tmpFile.Close()
return fmt.Errorf("sync L0 file: %w", err)
} // ENOSPC -> free space; EIO -> check dmesg for device errors Prevention
- Monitor disk free space and alert early
- Watch dmesg/smartd for device I/O errors
- Avoid tmpfs/overlay quirks for the LTX directory in containers
- Leave free-space headroom larger than your largest L0 file
When it happens
Trigger: checkDatabaseBehindReplica calls tmpFile.Sync() after a successful io.Copy and the OS returns an error — typically ENOSPC (no space left to flush dirty pages) or EIO (underlying device failure).
Common situations: Disk filling up between the copy and the sync; failing or failing-over storage hardware; container filesystems (some overlay/tmpfs setups) returning errors on fsync.
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
AI-assisted analysis of benbjohnson/litestream@4ed7a308f6 (2026-09-06).
Data as JSON: /api/errors/1fd0fa50fce6e3d9.
Report an issue: GitHub.