benbjohnson/litestream · error
create hydration file: %w
Error message
create hydration file: %w
What it means
After any stale state is cleared, Hydrator.Init creates/opens the hydration database file with os.OpenFile(path, O_RDWR|O_CREATE|O_TRUNC, 0600). This error wraps that failure. It is the final and most common step of hydration initialization, so any file-creation problem in the hydration directory surfaces here.
Source
Thrown at vfs.go:703
if txid, err := h.loadMeta(); err == nil {
if _, statErr := os.Stat(h.path); statErr == nil {
file, err := os.OpenFile(h.path, os.O_RDWR, 0600)
if err != nil {
return fmt.Errorf("open persistent hydration file: %w", err)
}
h.file = file
h.txid = txid
return nil
}
}
if err := os.Remove(h.metaPath()); err != nil && !os.IsNotExist(err) {
return fmt.Errorf("remove stale hydration meta: %w", err)
}
}
file, err := os.OpenFile(h.path, os.O_RDWR|os.O_CREATE|os.O_TRUNC, 0600)
if err != nil {
return fmt.Errorf("create hydration file: %w", err)
}
h.file = file
return nil
}
// Complete returns true if hydration has completed.
func (h *Hydrator) Complete() bool {
return h.complete.Load()
}
// SetComplete marks hydration as complete.
func (h *Hydrator) SetComplete() {
h.complete.Store(true)
}
// Disable temporarily disables hydrated reads (used during time travel).
func (h *Hydrator) Disable() {
h.complete.Store(false)View on GitHub (pinned to 4ed7a308f6)
Solutions
- Check free space on the filesystem of the hydration path (df -h) and free or expand it.
- Ensure the hydration directory is writable by the process user and that hydrationPath names a file, not a directory.
- Confirm no MAC policy (SELinux/AppArmor) blocks file creation there; check audit logs.
- Point hydrationPath at a dedicated writable volume sized for the database.
Example fix
// before
hydrator := NewHydrator("/mnt/ro-vol/hydration.db") // read-only mount
// after
hydrator := NewHydrator("/mnt/writable-vol/hydration.db") // rw mount with free space Defensive patterns
Strategy: validation
Validate before calling
p := hydrator.Path()
if fi, err := os.Stat(p); err == nil && fi.IsDir() {
return fmt.Errorf("hydration path %q is a directory", p)
}
if err := unix.Access(filepath.Dir(p), unix.W_OK); err != nil {
return fmt.Errorf("hydration dir not writable: %w", err)
} Try / catch
if err := hydrator.Init(); err != nil && strings.Contains(err.Error(), "create hydration file") {
// check disk space (ENOSPC), perms, and that path is not a directory
} Prevention
- Size the hydration volume for the full database and alert on usage.
- Ensure hydrationPath names a file, never a directory.
- Confirm SELinux/AppArmor policy permits creation there.
- Test hydration init in staging with production-like volumes and users.
When it happens
Trigger: Init on a fresh or cleared hydrator where the hydration file cannot be created — directory permissions deny write, disk full, path exceeds NAME_MAX, or the path exists as a directory.
Common situations: Disk-full on the volume holding the hydration path; hydrationPath accidentally pointing at a directory; SELinux denials on file creation; tiny ephemeral volumes filling up during hydration of large databases.
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 hydration directory: %w
- open persistent hydration file: %w
- remove stale hydration meta: %w
- open wal file: %w
- rename to output path: %w
AI-assisted analysis of benbjohnson/litestream@4ed7a308f6 (2026-09-06).
Data as JSON: /api/errors/4717acafa7a9befa.
Report an issue: GitHub.