benbjohnson/litestream · error

read page size from database header: %w

Error message

read page size from database header: %w

What it means

follow() failed to read the page size from the SQLite header of the restored database (offset 16, 2 bytes, big-endian). The file is too short or the header magic is invalid — the restore produced a non-database file.

Source

Thrown at replica.go:817

}

// follow enters a continuous restore loop, polling for new LTX files and
// applying them to the restored database. It blocks until the context is
// cancelled (e.g. Ctrl+C). Returns nil on clean shutdown.
func (r *Replica) follow(ctx context.Context, outputPath string, lastTXID ltx.TXID, interval time.Duration) error {
	f, err := os.OpenFile(outputPath, os.O_RDWR, 0)
	if err != nil {
		return fmt.Errorf("open database for follow: %w", err)
	}
	defer func() {
		_ = f.Sync()
		_ = f.Close()
	}()

	// Read page size from SQLite header (offset 16, 2 bytes, big-endian).
	var buf [2]byte
	if _, err := f.ReadAt(buf[:], 16); err != nil {
		return fmt.Errorf("read page size from database header: %w", err)
	}
	pageSize := uint32(buf[0])<<8 | uint32(buf[1])
	if pageSize == 1 {
		pageSize = 65536
	}

	if interval <= 0 {
		interval = DefaultFollowInterval
	}

	r.Logger().Info("entering follow mode", "output", outputPath, "txid", lastTXID, "interval", interval)

	ticker := time.NewTicker(interval)
	defer ticker.Stop()

	var consecutiveErrors int
	for {
		select {

View on GitHub (pinned to 4ed7a308f6)

Solutions

  1. Verify the restored file is a valid SQLite database (sqlite3 pragma header_check or file inspection)
  2. Re-run the restore from a known-good replica state
Defensive patterns

Strategy: validation

When it happens

Trigger: Thrown at replica.go:817 when the library encounters an invalid state.

Common situations: See trigger scenarios.


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