benbjohnson/litestream · warning
create temp meta file: %w
Error message
create temp meta file: %w
What it means
Hydrator.saveMeta wraps os.CreateTemp failures in the meta file's directory as "create temp meta file". saveMeta persists the current TXID atomically by writing a temp file and renaming it; if a temp file cannot be created, the meta save aborts (litestream logs a warning and continues, since hydration resume is best-effort).
Source
Thrown at vfs.go:989
if err != nil {
return 0, err
}
v, err := strconv.ParseUint(strings.TrimSpace(string(data)), 10, 64)
if err != nil {
return 0, fmt.Errorf("parse hydration meta: %w", err)
}
return ltx.TXID(v), nil
}
func (h *Hydrator) saveMeta() error {
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)View on GitHub (pinned to 4ed7a308f6)
Solutions
- Verify the directory containing the hydration file is writable by the litestream user (ls -ld, check uid)
- Free disk space / check inode usage (df -i)
- Do not point the hydration path at a read-only or ephemeral volume
- Note: saveMeta failures only cost hydration-resume on restart — fix the filesystem, restart litestream to re-hydrate
Defensive patterns
Strategy: validation
Validate before calling
// ensure the meta directory is writable before opening the VFS
dir := filepath.Dir(hydrationPath)
probe, err := os.CreateTemp(dir, ".probe-*")
if err != nil {
// fix permissions/ownership before starting litestream
} else {
probe.Close(); os.Remove(probe.Name())
} Prevention
- Run litestream as a user with write access to the hydration directory
- Avoid read-only or noexec-mounted volumes for hydration state
- Check df -i for inode exhaustion, not just df -h
- Remember this failure only disables resume; replication continues unaffected
When it happens
Trigger: Creating .hydration-meta-* in the hydration directory fails because the directory was deleted, is read-only, or lacks write permission; the filesystem is full (temp inode creation can still fail on some systems); path is on a read-only remount.
Common situations: Container running as non-root writing to a root-owned directory; hydration path pointing at a read-only volume; the hydration directory removed by a cleaner while litestream runs.
Understand the failure class
Background: "Permission denied" / "Failed to write" file errors: why a library can't write its files to disk (EACCES, EPERM, ENOSPC) and how to fix them — this error's family across 43 libraries.
Related errors
- cannot access output path: %w
- cannot access SQLite sidecar path: %w
- remove existing output path: %w
- remove ltx directory: %w
- stat database: %w
AI-assisted analysis of benbjohnson/litestream@4ed7a308f6 (2026-09-06).
Data as JSON: /api/errors/8c1e0c7eb068dcb7.
Report an issue: GitHub.