benbjohnson/litestream · error

write page %d to hydrated file: %w

Error message

write page %d to hydrated file: %w

What it means

Hydrator.WritePage wraps a failure writing a single page into the hydrated file as "write page %d to hydrated file". This is the VFS write path: SQLite hands a dirty page to litestream, which persists it into the local hydration file at (pgno-1)*pageSize.

Source

Thrown at vfs.go:923

		}

		off := int64(pgno-1) * int64(h.pageSize)
		if _, err := h.file.WriteAt(data, off); err != nil {
			return fmt.Errorf("write updated page %d: %w", pgno, err)
		}
	}

	return nil
}

// WritePage writes a single page to the hydration file.
func (h *Hydrator) WritePage(pgno uint32, data []byte) error {
	h.mu.Lock()
	defer h.mu.Unlock()

	off := int64(pgno-1) * int64(h.pageSize)
	if _, err := h.file.WriteAt(data, off); err != nil {
		return fmt.Errorf("write page %d to hydrated file: %w", pgno, err)
	}
	return nil
}

// Truncate truncates the hydration file to the specified size.
func (h *Hydrator) Truncate(size int64) error {
	h.mu.Lock()
	defer h.mu.Unlock()
	return h.file.Truncate(size)
}

// Close closes the hydration file. For persistent hydrators, the file and a
// companion .meta file are preserved so hydration can resume on the next open.
func (h *Hydrator) Close() error {
	if h.file == nil {
		return nil
	}

View on GitHub (pinned to 4ed7a308f6)

Solutions

  1. Free disk space or enlarge the volume holding the hydration file — this is the most common cause
  2. Inspect the wrapped error for errno (ENOSPC, EIO, EBADF) to pick the right remedy
  3. If EBADF, check for a shutdown/close race in your embedding code that closes the VFS while writes are in flight
  4. Use litestream reset if the hydration file is corrupted
Defensive patterns

Strategy: try-catch

Validate before calling

if fi, err := os.Stat(hydrationPath); err != nil {
	// hydration file missing — re-hydrate instead of writing
}

Try / catch

if err := hydrator.WritePage(pgno, data); err != nil {
	if errors.Is(err, syscall.ENOSPC) {
		// transaction will fail; free space before retrying
	}
}

Prevention

When it happens

Trigger: Disk full during a SQLite transaction commit; WriteAt issued after the hydration file was closed; underlying storage returning EIO; data slice length exceeding expectations is not the cause here — only pwrite failures.

Common situations: Out-of-space conditions on busy databases; nodes with read-only remounted filesystems after errors; container volume limits reached; fd closed early due to a shutdown race.

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/0f7d5d91a04eb088. Report an issue: GitHub.