In short
IntactFile recovers corrupt SQLite databases (.db/.sqlite/.sqlite3) that fail with "database disk image is malformed" or "file is not a database": it scans the pages directly, rebuilds the schema, and writes every row it can still decode into a fresh, openable database. It runs entirely in your browser — the database is never uploaded, and you can confirm 0 bytes leave your device in the Network tab. The honest limit: rows physically overwritten or truncated off the file, and encrypted databases without the key, can't be brought back — only what still survives on disk.
Database won't open? Recover it now
- Drop the .db / .sqlite file
- Recovery runs locally
- Download a fresh, openable database
To recover a malformed SQLite database you don't "fix" the broken file in place — you read out everything that's still decodable and write it into a brand-new database, exactly the way SQLite's own.recover command works. That runs right here in your browser: drop the file above, the diagnosis shows what's damaged, and the recovery engine rebuilds the schema and re-inserts every row it can read. Nothing is installed, and the database is never uploaded.
The errors this covers
Error: database disk image is malformed (11)The classic SQLITE_CORRUPT. Something in the file's page structure is inconsistent — a corrupt b-tree page, a bad cell pointer, a page count that disagrees with the file size. The engine stops at the first problem it hits, but the pages it never reached are usually fine, and a raw scan can pull the rows straight out of them.
file is not a databaseSQLite says this when the 16-byte header magic ("SQLite format 3\0") is wrong. Two very different causes: the header bytes were damaged (the pages behind them are often intact and recoverable), or the file is genuinely something else — or an encrypted (SQLCipher/SEE) database, which reads as high-entropy noise and can't be recovered without the key. The diagnosis tells the two apart.
database or disk is full / malformed database schemaDownstream symptoms of the same underlying page damage. If re-opening the file produces the same failure, in-place fixes have run out and a rebuild from the surviving pages is the next step.
How a SQLite file breaks: pages and pointers
A SQLite database is a flat array of fixed-size pages(usually 4 KB each). Page 1 holds the header and the schema; every table and index is a b-tree whose interior pages point down to leaf pages that hold your actual rows. Software reads the header, finds the schema, then follows those pointers to the data.
The pointers are the weakness. A single interrupted write, a bad sector, a sync that stopped halfway, or a byte flip in one interior page and the pointer chain breaks — SQLite hits an inconsistency and declares the whole image malformed, even though your rows are still sitting in their leaf pages untouched. It's the same story as a video's missing index or a ZIP's broken central directory: the map broke, not the data.
That's why recovery works: leaf pages carry self-describing records, so the engine can walk the file page by page, decode the rows it finds, and rebuild the b-trees from scratch around them. Rows the pointers can't reach are found by a raw sweep; rows that match no known table go to alost_and_found table instead of being thrown away.
If you have a -wal file, bring it
Databases in WAL mode stage recent changes in a sibling<name>-wal file until they're checkpointed into the main database. After a crash, your newest committed data can live only there. Drop the main .db first, then add the-wal file in the optional sidecar slot: its committed frames are overlaid before the scan, so the recovered database reflects the last committed transaction rather than the last checkpoint. It's optional — recovery runs fine on the main file alone — but if you have the sidecar, it's often where the freshest rows are.
Why no-upload matters for databases
Think about what a database actually contains: user accounts, messages, location history, an app's entire state. It's the single file you'd least want sitting on someone else's server "just to repair it". Upload-based recovery tools copy it off your machine and process it on infrastructure you can't inspect. In-browser recovery removes that step entirely — the file is read from your disk, rebuilt in your tab, and no copy exists anywhere else. For DFIR work on evidence, that also keeps chain-of-custody intact: the artifact never leaves the workstation. You can verify it in the Network tab while recovery runs.
What this can and can't recover
Can recover
- "Database disk image is malformed" from a damaged page or b-tree pointer
- Corrupt header fields (wrong page size or page count) with intact pages behind them
- Truncated files: every row on a surviving page is pulled out
- Rows on pages the pointer chain can no longer reach, via a raw page scan
- Uncheckpointed changes from a supplied
-walsidecar
Can't recover
- Rows physically overwritten or truncated off the end — that data no longer exists
- Encrypted databases (SQLCipher/SEE) without the key — the pages are ciphertext
- Exact column affinities: values come back as their on-disk storage class
- A guarantee of correctness — recovered data is always suspect; verify it
- 0-byte files: that's a data-recovery problem for the storage device first
The recovery report lists what came out of each table, flags rows pulled by the raw scan or dropped as undecodable, and a failed recovery is never charged.