benbjohnson/litestream · error
write txid: %w
Error message
write txid: %w
What it means
WriteTXIDFile wraps a failure writing the TXID line to the temporary file via fmt.Fprintln. This is rare (usually disk-full ENOSPC or an I/O error on the underlying file handle) but the TXID marker could not be persisted, so restore cannot safely record the last applied transaction.
Source
Thrown at replica.go:1732
func TXIDPath(outputPath string) string {
return outputPath + "-txid"
}
// WriteTXIDFile atomically writes a TXID to a sidecar file at <outputPath>-txid.
// Uses temp-file + fsync + rename for crash safety.
func WriteTXIDFile(outputPath string, txid ltx.TXID) error {
txidPath := TXIDPath(outputPath)
tmpPath := txidPath + ".tmp"
f, err := os.Create(tmpPath)
if err != nil {
return fmt.Errorf("create txid temp file: %w", err)
}
defer f.Close()
defer os.Remove(tmpPath)
if _, err := fmt.Fprintln(f, txid); err != nil {
return fmt.Errorf("write txid: %w", err)
}
if err := f.Sync(); err != nil {
return fmt.Errorf("sync txid file: %w", err)
}
if err := f.Close(); err != nil {
return fmt.Errorf("close txid file: %w", err)
}
if err := os.Rename(tmpPath, txidPath); err != nil {
return fmt.Errorf("rename txid file: %w", err)
}
if err := internal.FsyncDir(filepath.Dir(txidPath)); err != nil {
return fmt.Errorf("sync txid dir: %w", err)
}
return nilView on GitHub (pinned to 4ed7a308f6)
Solutions
- Free disk space or expand the volume, then re-run the restore.
- Check dmesg/journal for I/O errors on the target device and replace failing media.
- Restore to a healthy local path and sync to the final location afterwards.
- Re-run the restore; the .tmp file is removed on failure so no partial state is left.
Example fix
// before // error: write txid: write /data/db.sqlite.txid.tmp: no space left on device $ df -h /data # 100% used // after $ rm /data/old-backups/* # or expand volume $ litestream restore -o /data/db.sqlite db
Defensive patterns
Strategy: validation
Validate before calling
// Go: check free space on the target filesystem before restore
var st syscall.Statfs_t
if err := syscall.Statfs(dir, &st); err == nil {
avail := int64(st.Bavail) * int64(st.Bsize)
if avail < minRequiredBytes {
return fmt.Errorf("insufficient space: %d bytes free", avail)
}
} Try / catch
if err := WriteTXIDFile(path, txid); err != nil {
if strings.Contains(err.Error(), "write txid") {
// almost always ENOSPC or device I/O error: free space / check dmesg, then re-run
}
return err
} Prevention
- Monitor disk usage and alert before volumes reach capacity.
- Avoid restoring to flaky network filesystems; restore locally then sync.
- Re-run restores after transient write failures: .tmp files are cleaned up automatically.
When it happens
Trigger: Disk filling up mid-write during restore; I/O errors on failing storage; filesystem quota exceeded while writing <output>.txid.tmp.
Common situations: DR recovery on an almost-full volume; network filesystems returning short writes/EIO; container ephemeral storage quota hit during a large 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
- create txid temp file: %w
- cannot access output path: %w
- cannot restore, output path is a directory: %s
- cannot restore, output path already exists and is not empty:
- cannot access SQLite sidecar path: %w
AI-assisted analysis of benbjohnson/litestream@4ed7a308f6 (2026-09-06).
Data as JSON: /api/errors/acb6f73800a4753e.
Report an issue: GitHub.