tursodatabase/turso · error

database page number does not fit u32

Error message

database page number does not fit u32: {page_no}

What it means

While iterating pages 1..=db_size for a replace-base snapshot, a page number failed u32::try_from when calling the page-read API. SQLite-format page numbers are inherently 32-bit, so a db_size with pages beyond u32::MAX implies a malformed or corrupt size (a 16+ TiB database), not a realistic file.

Solutions

  1. Verify the database file and WAL integrity (dbhash / integrity check) and restore from backup
  2. Confirm the db and WAL files belong together and were not truncated or swapped
Defensive patterns

Strategy: validation

Type guard

fn fits_u32(v: u64) -> bool {
    u32::try_from(v).is_ok()
}

Prevention

When it happens

Trigger: read_replace_base_pages encounters a db_size (from current_snapshot_db_size_pages) larger than u32::MAX, so some page_no in the loop overflows the u32 the try_wal_watermark_read_page API requires.

Common situations: Corrupt database header or WAL-driven size metadata; bit-flipped size fields; not producible by valid SQLite-format databases of realistic size.

Related errors


AI-assisted analysis of tursodatabase/turso@492c4a71cd (2026-08-20). Data as JSON: /api/errors/1254910bed833d2f. Report an issue: GitHub.

Appendix: source

Thrown at cli/sync_server.rs:972

            status: 200,
            content_type: "application/protobuf".to_string(),
            body: response_body,
        })
    }

    #[allow(clippy::type_complexity)]
    fn read_replace_base_pages(&self, db: &DbHandle) -> Result<(u64, Vec<(u64, Vec<u8>)>)> {
        let conn = db.conn.lock().unwrap();
        let wal_state = conn.wal_state()?;
        let frame_watermark = Some(wal_state.max_frame);
        let db_size = current_snapshot_db_size_pages(&conn, wal_state.max_frame)?;
        let pages_capacity = usize::try_from(db_size)
            .map_err(|_| anyhow!("database page count does not fit usize: {db_size}"))?;
        let mut pages = Vec::with_capacity(pages_capacity);

        for page_no in 1..=db_size {
            let page_no_u32 = u32::try_from(page_no)
                .map_err(|_| anyhow!("database page number does not fit u32: {page_no}"))?;
            let mut page = vec![0; PAGE_SIZE];
            let found =
                conn.try_wal_watermark_read_page(page_no_u32, &mut page, frame_watermark)?;
            if !found {
                return Err(anyhow!(
                    "database page {} is missing from replace-base snapshot",
                    page_no
                ));
            }
            pages.push((page_no - 1, page));
        }

        Ok((db_size, pages))
    }
}

struct HttpResponse {
    status: u16,

View on GitHub (pinned to 492c4a71cd)