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

  1. Verify the directory containing the hydration file is writable by the litestream user (ls -ld, check uid)
  2. Free disk space / check inode usage (df -i)
  3. Do not point the hydration path at a read-only or ephemeral volume
  4. 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

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


AI-assisted analysis of benbjohnson/litestream@4ed7a308f6 (2026-09-06). Data as JSON: /api/errors/8c1e0c7eb068dcb7. Report an issue: GitHub.