tursodatabase/turso · error
Page size too small, a ptrmap page cannot map any db pages.
Error message
Page size too small, a ptrmap page cannot map any db pages.
What it means
A pointer-map page holds one 5-byte entry per mapped database page; ptrmap_page_cycle_length derives how many entries fit in a page. If the page size is so small that zero entries fit, get_ptrmap_page_no_for_db_page panics. With SQLite's minimum page size of 512 bytes this is unreachable from valid databases - it guards against malformed or custom page sizes reaching the ptrmap math.
Source
Thrown at core/storage/pager.rs:6374
/// Determines if a given page number `db_page_no` (1-indexed) is a pointer map page in a database with autovacuum enabled
pub fn is_ptrmap_page(db_page_no: u32, page_size: usize) -> bool {
// The first page cannot be a ptrmap page because its for the schema
if db_page_no == 1 {
return false;
}
if db_page_no == FIRST_PTRMAP_PAGE_NO {
return true;
}
get_ptrmap_page_no_for_db_page(db_page_no, page_size) == db_page_no
}
/// Calculates which pointer map page (1-indexed) contains the entry for `db_page_no_to_query` (1-indexed).
/// `db_page_no_to_query` is the page whose ptrmap entry we are interested in.
pub fn get_ptrmap_page_no_for_db_page(db_page_no_to_query: u32, page_size: usize) -> u32 {
let group_size = ptrmap_page_cycle_length(page_size) as u32;
if group_size == 0 {
panic!("Page size too small, a ptrmap page cannot map any db pages.");
}
let effective_page_index = db_page_no_to_query - FIRST_PTRMAP_PAGE_NO;
let group_idx = effective_page_index / group_size;
(group_idx * group_size) + FIRST_PTRMAP_PAGE_NO
}
/// Calculates the byte offset of the entry for `db_page_no_to_query` (1-indexed)
/// within its pointer map page (`ptrmap_page_no`, 1-indexed).
pub fn get_ptrmap_offset_in_page(
db_page_no_to_query: u32,
ptrmap_page_no: u32,
page_size: usize,
) -> Result<usize> {
// The data pages mapped by `ptrmap_page_no` are:
// `ptrmap_page_no + 1`, `ptrmap_page_no + 2`, ..., up to `ptrmap_page_no + n_data_pages_per_group`.
// `db_page_no_to_query` must be one of these.View on GitHub (pinned to 492c4a71cd)
Solutions
- Validate page_size is >= 512 and a power of two before ptrmap computations
- If caused by a corrupt file: restore from backup or rebuild the database
- Fix the test to use a legal page size
Example fix
// before let p = get_ptrmap_page_no_for_db_page(page, tiny_page_size); // panics: zero entries fit // after assert!(page_size >= 512 && page_size.is_power_of_two()); let p = get_ptrmap_page_no_for_db_page(page, page_size);
Defensive patterns
Strategy: validation
Validate before calling
fn valid_page_size(ps: usize) -> bool {
(512..=65536).contains(&ps) && ps.is_power_of_two()
}
assert!(valid_page_size(page_size)); Prevention
- Centralize page-size validation at header parse time so ptrmap math never sees garbage
- Point fuzz targets at the validator so corrupt sizes are rejected at the boundary
When it happens
Trigger: Computing ptrmap page numbers with a page size smaller than the entry size: unit tests passing tiny page sizes, or corrupted-header parsing feeding an invalid page size onward (auto_vacuum pointer-map code).
Common situations: Unit tests with hand-rolled page sizes; fuzzed or corrupt database headers skipping validation.
Related errors
- invalid page size stored
- DB should not be initialized and should not do any IO
- buffer not loaded
- subjournal must be opened
- in practice, clear_savepoints() should never fail as it uses
AI-assisted analysis of tursodatabase/turso@492c4a71cd (2026-08-20).
Data as JSON: /api/errors/8f8a4b5989e396ea.
Report an issue: GitHub.