benbjohnson/litestream · error

unsupported page size: %d

Error message

unsupported page size: %d

What it means

When determining the SQLite page size from replica LTX headers, a header reported a page size that the VFS does not support (SQLite valid sizes are 512–65536 powers of two). The VFS refuses to proceed with an unusable page size.

Source

Thrown at vfs.go:2794

	pageSize := f.pageSize
	f.mu.Unlock()
	if pageSize == 0 {
		f.logger.Debug("page size not initialized", "pageSize", 0)
		return 0, &DBNotReadyError{Reason: "page size not initialized"}
	}
	return pageSize, nil
}

func detectPageSizeFromInfos(ctx context.Context, client ReplicaClient, infos []*ltx.FileInfo) (uint32, error) {
	var lastErr error
	for i := len(infos) - 1; i >= 0; i-- {
		pageSize, err := readPageSizeFromInfo(ctx, client, infos[i])
		if err != nil {
			lastErr = err
			continue
		}
		if !isSupportedPageSize(pageSize) {
			return 0, fmt.Errorf("unsupported page size: %d", pageSize)
		}
		return pageSize, nil
	}
	if lastErr != nil {
		return 0, fmt.Errorf("read ltx header: %w", lastErr)
	}
	return 0, fmt.Errorf("no ltx file available to determine page size")
}

func readPageSizeFromInfo(ctx context.Context, client ReplicaClient, info *ltx.FileInfo) (uint32, error) {
	rc, err := client.OpenLTXFile(ctx, info.Level, info.MinTXID, info.MaxTXID, 0, ltx.HeaderSize)
	if err != nil {
		return 0, fmt.Errorf("open ltx file: %w", err)
	}
	defer rc.Close()
	dec := ltx.NewDecoder(rc)
	if err := dec.DecodeHeader(); err != nil {
		return 0, fmt.Errorf("decode ltx header: %w", err)

View on GitHub (pinned to 4ed7a308f6)

Solutions

  1. Inspect the first LTX file's header bytes to verify the page-size field
  2. Re-replicate the database from the primary to replace corrupt LTX files
  3. Run `litestream reset` to clear local state and rehydrate from the replica
  4. Ensure the database uses a standard page size (PRAGMA page_size) such as 4096

Example fix

// before
PRAGMA page_size=3000;  -- invalid for SQLite/litestream
// after
PRAGMA page_size=4096;  -- then re-replicate
Defensive patterns

Strategy: validation

Validate before calling

func validPageSize(ps uint32) bool {
    return ps >= 512 && ps <= 65536 && ps&(ps-1) == 0
}
// check on primary: PRAGMA page_size must pass validPageSize

Prevention

When it happens

Trigger: readPageSizeFromInfo returned a value failing isSupportedPageSize — typically a zero/garbage value from a truncated or corrupt LTX header, or a database created with an exotic page size.

Common situations: Corrupt or truncated first LTX file in the replica; files written by an incompatible litestream version; manually edited LTX data in storage.

Understand the failure class

Background: "Invalid value" and "allowed values are" config errors: what your library rejected and how to fix it — this error's family across 41 libraries.

Related errors


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