benbjohnson/litestream · warning
write hydration meta: %w
Error message
write hydration meta: %w
What it means
Hydrator.saveMeta wraps fmt.Fprintf failures writing the TXID into the temp meta file as "write hydration meta". On failure the temp file is closed and removed, and the error is returned; the caller (Close) logs it as a warning because losing the meta only affects resume-on-restart.
Source
Thrown at vfs.go:1000
h.mu.Lock()
txid := h.txid
h.mu.Unlock()
dir := filepath.Dir(h.metaPath())
tmp, err := os.CreateTemp(dir, ".hydration-meta-*")
if err != nil {
return fmt.Errorf("create temp meta file: %w", err)
}
tmpPath := tmp.Name()
if _, err := fmt.Fprintf(tmp, "%d\n", txid); err != nil {
if closeErr := tmp.Close(); closeErr != nil {
h.logger.Warn("failed to close temp meta file during cleanup", "error", closeErr)
}
if removeErr := os.Remove(tmpPath); removeErr != nil {
h.logger.Warn("failed to remove temp meta file during cleanup", "error", removeErr)
}
return fmt.Errorf("write hydration meta: %w", err)
}
if err := tmp.Sync(); err != nil {
if closeErr := tmp.Close(); closeErr != nil {
h.logger.Warn("failed to close temp meta file during cleanup", "error", closeErr)
}
if removeErr := os.Remove(tmpPath); removeErr != nil {
h.logger.Warn("failed to remove temp meta file during cleanup", "error", removeErr)
}
return fmt.Errorf("sync temp meta file: %w", err)
}
if err := tmp.Close(); err != nil {
if removeErr := os.Remove(tmpPath); removeErr != nil {
h.logger.Warn("failed to remove temp meta file during cleanup", "error", removeErr)
}
return fmt.Errorf("close temp meta file: %w", err)
}
if err := os.Rename(tmpPath, h.metaPath()); err != nil {
if removeErr := os.Remove(tmpPath); removeErr != nil {View on GitHub (pinned to 4ed7a308f6)
Solutions
- Check free space on the volume holding the hydration meta (df -h, df -i)
- If on NFS/network storage, check mount health and consider local disk for hydration state
- This error is non-fatal for replication — the next Close with a healthy filesystem will persist the meta again
Defensive patterns
Strategy: retry
Validate before calling
if stat, err := os.Stat(dir); err != nil || !stat.IsDir() {
// hydration directory missing — recreate before opening
} Try / catch
if err := saveMeta(); err != nil {
if isTransientIO(err) { time.Sleep(time.Second); err = saveMeta() }
} Prevention
- Use local disks rather than NFS for hydration state
- Monitor filesystem I/O errors in dmesg
- Keep headroom on metadata-heavy volumes
- Treat this as non-fatal: meta is a resume optimization only
When it happens
Trigger: The temp file's filesystem returns ENOSPC mid-write; the file descriptor becomes invalid (disk ejected, network filesystem dropped); write on a quota-exceeded volume.
Common situations: Small metadata volume that is full; NFS/network mounts with transient I/O failures; disk-hot-remove on VMs.
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
- failed to scan directory %s: %w
- cannot remove tmp files: %w
- close L0 file: %w
- write page %d: %w
- sync before truncate: %w
AI-assisted analysis of benbjohnson/litestream@4ed7a308f6 (2026-09-06).
Data as JSON: /api/errors/165a231290f18ee9.
Report an issue: GitHub.