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

  1. Check free space on the volume holding the hydration meta (df -h, df -i)
  2. If on NFS/network storage, check mount health and consider local disk for hydration state
  3. 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

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


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