benbjohnson/litestream · error

unsupported page size

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.

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.

Appendix: 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)