Fix it now
- Drop the file
- Repair runs locally
- Download the result
places.sqlite is the single SQLite database where Firefox keeps your entire browsing history, every bookmark, plus tags, keywords and page annotations. When it goes bad you either see Firefox silently reset — bookmarks reappear but history is gone — or a tool reports "database disk image is malformed". That is SQLite's SQLITE_CORRUPT (result code 11): one page or pointer broke and the engine refuses the whole file, even though your rows are usually still sitting untouched in their leaf pages. Drop places.sqlite (or the places.sqlite.corrupt file Firefox left behind) above and the recovery walks the pages in your browser, rebuilds the schema, and writes a fresh, openable database — nothing is uploaded.
What places.sqlite holds, and what actually broke
Everything in Firefox's bookmarks-and-history system lives in one file. moz_places holds one row per URL you've ever visited or bookmarked — its url, title, rev_host (the host reversed, for fast domain grouping), visit_count, last_visit_date, a guid, a url_hash, and frecency, a Firefox-only score blending frequency and recency that ranks the address-bar suggestions. Each actual visit is a row in moz_historyvisits, whose place_id points back at moz_places.id. Your bookmark tree is moz_bookmarks: each row carries a parent, a position, a title, a guid, and an fk foreign key into moz_places. The tree hangs off fixed root folders with permanent 12-character guids — root________, menu________ (Bookmarks Menu), toolbar_____ (Bookmarks Toolbar), unfiled_____ (Other Bookmarks), mobile______ and tags________. Around them sit moz_origins, moz_keywords, the moz_anno_attributes/moz_annos/moz_items_annos annotation tables, moz_inputhistory, and moz_meta. Favicons are not here — since Firefox 55 they live in a separate favicons.sqlite in the same profile.
Physically, the file is a flat array of fixed-size pages. Firefox builds places.sqlite with a 32 KiB page size (PRAGMA page_size = 32768, compiled in as SQLITE_DEFAULT_PAGE_SIZE) — eight times SQLite's 4 KiB default — and runs it in WAL mode, so you'll see two sidecars next to it: places.sqlite-wal (the write-ahead log) and places.sqlite-shm (a shared-memory index). Page 1 holds the header and the schema; every table and index is a b-tree whose interior pages point down to the leaf pages that hold your rows.
Those pointers are the weak point. An interrupted write, a crash mid-checkpoint, a full disk, a bad sector, or a byte flip in one 32 KiB interior page is enough: SQLite follows the pointer, finds something that isn't a valid page, and declares the whole image malformed — while your rows sit intact in the leaf pages it never reached. The map broke, not the data.
What Firefox does when it finds the corruption — and why history disappears
Firefox checks places.sqlite as it starts. If the open hits SQLITE_CORRUPT or an integrity check fails, the Places service treats the file as unusable and does something drastic without asking: it renames places.sqlite to places.sqlite.corrupt in the profile folder, creates a brand-new empty places.sqlite, and then restores your bookmarks from the newest dated file in the bookmarkbackups folder — bookmarks-YYYY-MM-DD_<count>_<hash>.jsonlz4, compressed with Mozilla's mozLz4 (an 8-byte mozLz40\0 magic, then a 4-byte little-endian decompressed size, then an LZ4 block — not plain LZ4, so ordinary tools can't open it).
Here is the catch that sends people looking for a fix: only bookmarks are backed up that way. History, frecency scores, keywords and input history are never written to those .jsonlz4 files, so a reset quietly rebuilds your bookmark tree and drops everything else. Your bookmarks come back looking fine; months or years of history are simply gone from the live database.
The error strings you'll actually see, and what they mean: database disk image is malformed is SQLITE_CORRUPT (result code 11) — a bad page, cell offset, or a page count that disagrees with the file size. file is not a database is SQLITE_NOTADB (code 26): the 16-byte header magic SQLite format 3\000 is damaged, though the pages behind it are often intact. And The bookmarks and history system will not be functional because one of Firefox's files is in use by another application is a different beast — that's a lock (SQLITE_BUSY), usually a second Firefox process or an antivirus holding the file, not corruption. Because the rename happens automatically, by the time you notice the empty toolbar the good data already sits in places.sqlite.corrupt and the live places.sqlite is blank.
How the recovery rebuilds it locally
Rather than patch the broken file in place, the tool reads its 32 KiB pages directly, reconstructs the schema from page 1, walks each table's b-tree, and falls back to a pointer-free raw page scan for the rows the broken pointers can no longer reach — the same strategy as SQLite's own .recover command. Records that can't be attributed to a known table are placed in a lost_and_found table instead of being discarded, so a mangled moz_places or moz_bookmarks row is preserved rather than dropped. If you still have the places.sqlite-wal sidecar, add it in the optional slot: in WAL mode the newest visits and bookmarks may live only in that log until they're checkpointed, and its committed frames are overlaid before the scan. The output is a fresh, openable places.sqlite you download — copy it back into the profile with Firefox closed, or open it read-only to export bookmarks and history.
Feed the places.sqlite.corrupt file if Firefox has already reset your profile — that's where your history still is. To find it, open about:profiles and click "Open Directory" (Root Directory) for the profile in use, or go straight to %APPDATA%\Mozilla\Firefox\Profiles\<name> on Windows, ~/Library/Application Support/Firefox/Profiles/<name> on macOS, or ~/.mozilla/firefox/<name> on Linux. Copy the file out while Firefox is fully closed so nothing holds a lock on it.
Why this must not be uploaded: places.sqlite is, quite literally, a complete log of every page you have ever visited. It is the single file you'd least want copied onto a repair company's server "just to fix it", under retention terms you never read. Here it's read from your disk and rebuilt in the browser tab — you can open the Network panel and confirm 0 bytes of the database ever leave your machine.
What this can and can't fix
Can fix
- "database disk image is malformed" from a damaged 32 KiB page or a broken b-tree pointer, when the leaf pages holding your rows survive
- The history Firefox drops on reset — moz_places and moz_historyvisits rows walked straight out of the file after a bookmarks-only restore
- The places.sqlite.corrupt file Firefox renamed when it reset your profile
- A damaged header ("file is not a database") when the pages behind the 16-byte SQLite magic are intact
- Uncheckpointed visits and bookmarks from a supplied places.sqlite-wal sidecar
Can't fix
- Rows physically overwritten or truncated off the end of the file — those bytes no longer exist
- A places.sqlite Firefox already replaced with a fresh empty database (recover the renamed .corrupt file instead)
- Rebuilding favicons — those live in a separate favicons.sqlite; recover that file on its own
- Decompressing a .jsonlz4 bookmark backup — that's a mozLz4 archive, not a SQLite database (import it from Firefox's own Library instead)
- A 0-byte file, or one that is high-entropy noise end to end (a storage-device data-recovery job comes first)
If a repair fails, we tell you why (missing data versus broken structure), and you are never charged for a failed repair.