Every SQLite file is a single file on disk, divided into equal-sized blocks called pages. The first page opens with a 100-byte header that marks the file as SQLite format 3. Everything after that header is a collection of pages holding tables, indexes, and free space. Grasp this structure and you will see why a small corruption can cost you a few rows, and why the wrong kind of damage wipes out everything.

The Database Header Page 1 and the 100 Byte Signature

The first 16 bytes of page 1 are the string SQLite format 3 followed by a zero byte. Software uses this string to recognise the file. Damage those bytes and no tool opens it.

The header carries metadata you cannot afford to lose. Offset 16 stores a 2-byte big-endian integer that sets the page size. The default is 4096 bytes. It can be any power of two from 512 to 32768. A stored value of 1 means 65536 bytes. Every multi-byte integer in the file is big-endian.

Offset 36 holds a 4-byte integer: the total number of pages on the freelist. Deleted pages sit on this list waiting for reuse. A corrupted freelist count makes the engine read freed pages as though they still contain valid data.

Page 1 also holds the root of the sqlite_schema table, so damage here is catastrophic. The schema table lists every table and index. Lose its root page and the engine cannot find any of your tables.

Page Types and B-Tree Basics

After page 1, every page begins with a one-byte type code. Four types serve B-trees:

  • 2, interior index page
  • 5, interior table page
  • 10, leaf index page
  • 13, leaf table page

Tables and indexes are B-trees. Interior pages hold pointers to child pages. Leaf pages hold the actual rows or index entries. The type byte tells the engine how to read the rest of the page.

Table B-Trees

Leaf pages (type 13) contain row data. Interior pages (type 5) store the minimum key values for each child page plus a pointer to that child. The root page number for every table B-tree sits in the sqlite_schema table.

Index B-Trees

Leaf pages (type 10) hold index entries. Interior pages (type 2) guide the search to the correct leaf. Indexes speed up lookups. The file works without them.

Page Layout and the Page Size

Every page is exactly the size stored in the header. The default is 4096 bytes. Larger pages hold more data per page. That reduces the number of B-tree levels.

Each B-tree page carries a small header of its own: the page type (1 byte), the number of cells (2 bytes), offsets to the start of free space, and pointers to sibling pages for leaf pages. The rest of the page is cell content and free space.

Corrupt the page size and the engine cannot read any page correctly. This is a second reason header damage on page 1 is fatal.

The Sqlite_schema Table Why Page 1 is Critical

The sqlite_schema table describes the structure of the whole file. It lists every table, index, trigger, and view. Its root lives on page 1, right after the 100-byte header.

Opening a file, the engine reads the header for the page size, then reads the schema table from page 1 to learn the names and root page numbers of all your tables. Damage page 1 and the engine cannot find the schema. It cannot locate any of your data.

Damage elsewhere is different. A corrupted leaf page might lose a few rows. A corrupted interior page might make a small range of rows unreachable. The rest of the file remains readable.

Freelist Pages and Reclaimed Space

Delete rows or drop tables and the pages that held them are not wiped. They join a freelist, a linked list of pages available for reuse. The header at offset 36 records how many pages sit on that list.

The freelist lets the file reuse space without growing. But corrupt the freelist pointers and the engine might read a recycled page as valid data. It might also fail to find free space when it needs a new page.

Corruption Patterns Local Vs. Total Loss

The file format explains why some corruption is survivable and some is not.

  • Damage to a leaf page (type 13 or 10): Only the rows or index entries on that page are lost. The schema table stays intact. The table structure remains visible. Recover the rest of the data.
  • Damage to an interior page (type 5 or 2): You lose access to every row in the subtree under that page. The loss is larger than a leaf page but still confined to one branch of the B-tree.
  • Damage to page 1: The header or the schema root is corrupted. The engine cannot determine the page size, cannot read the schema, and cannot open the file at all. Total loss, unless you can repair the header.

If you have a corrupted SQLite file, tools that scan pages directly and bypass the damaged schema can attempt recovery.