Recover a corrupt WhatsApp database (msgstore.db)

WhatsApp keeps your whole chat history in a single SQLite file, msgstore.db. When one page or pointer breaks, SQLite refuses the entire file as malformed even though most of your messages are still sitting in it — and getting them back should never mean handing your chat database to a stranger's server.

Your file never leaves your device — repair runs in your browser. 0 bytes uploaded.

Your data is the big block — usually intact. What breaks is the small index. Repair rebuilds it.

Drop a file here or browseTap to choose a file

ZIP · Office · PDF · video · JPG · PNG · RAR/7z · SQLite — repaired right here in your browser. Nothing is uploaded

0 bytes uploadedFree: 3 repairs/day — up to 500 MB video, 100 MB docs & archives, 50 MB photos. Free download. Single repair €5.90. No account required.

Fix it now

  1. Drop the file
  2. Repair runs locally
  3. Download the result

WhatsApp on Android stores every conversation in a single SQLite database named msgstore.db — message text, timestamps, chat and contact references all live inside it. When an app crash, an interrupted copy off the phone, or a half-finished sync damages it, WhatsApp and every other SQLite tool refuse the whole file with "database disk image is malformed". Drop the decrypted msgstore.db above and the tool walks its pages locally, rebuilds the schema, and re-inserts every row it can still decode into a fresh, openable database — the chat DB, which holds your entire message history, is never uploaded.

What's inside msgstore.db — pages, tables and the -wal sidecar

A WhatsApp database is an ordinary SQLite file, so it's a flat array of fixed-size pages (SQLite's default is often 4 KB). The very first 16 bytes are the magic string SQLite format 3\0; the rest of page 1 holds the file header and the sqlite_schema that lists every table. Each table is a b-tree: interior pages carry pointers down to leaf pages, and the leaf pages hold your actual rows.

The tables that matter for chat history are predictable. Modern WhatsApp builds keep messages in a message table (older builds used messages), the conversation list in chat, and the phone-number/group identifiers in jid. Message text lives in a text column (text_data on the modern schema, data on the legacy one), and every row carries a timestamp in Unix epoch milliseconds. Supporting tables like message_media, message_thumbnail, message_quoted and call_log round it out. Crucially, the photos, videos and voice notes themselves are not in the database — those are separate files in the WhatsApp Media folder; the DB only stores their file paths plus small thumbnails.

WhatsApp runs the database in WAL (write-ahead logging) mode, so on the phone you'll see two sibling files next to it: msgstore.db-wal and msgstore.db-shm. Recent, committed messages can live only in the -wal file until they're checkpointed back into the main .db. If you have that sidecar, keep it — its committed frames are the newest rows.

Why it reports "malformed" — and the .crypt trap

SQLite raises SQLITE_CORRUPT (result code 11) — surfaced as "database disk image is malformed" — the moment it follows a pointer and lands on something that isn't a valid b-tree page: a zeroed page, a bad cell offset, a page count that disagrees with the file size. It stops at the first inconsistency, which is why one damaged interior page takes the whole file down while the untouched leaf pages behind it still hold your messages. A related error, "file is not a database," means the 16-byte header magic itself was mangled — the pages behind it are often fine.

The damage usually comes from an interrupted write. Pulling msgstore.db off a phone over USB or through a file manager while WhatsApp still has it open can copy a torn, half-checkpointed file; a byte flip on a failing SD card or in a sync, or a device that lost power mid-write, does the same. A truncated copy simply loses whatever pages were at the tail.

One trap catches people first: the file in WhatsApp's backup folder is not a plain database. Backups are named msgstore.db.crypt14 or msgstore.db.crypt15 and are AES-GCM encrypted (the key sits at /data/data/com.whatsapp/files/key, or, for crypt15, behind your end-to-end backup password). A .crypt14/.crypt15 file reads as high-entropy noise — it has no SQLite header at all, so page recovery can't touch it until it's decrypted back to a plain msgstore.db. This tool works on the decrypted database, not the encrypted backup.

What recovery pulls back — and why you never upload a chat DB

Instead of trusting the broken pointers, the tool reads the file page by page: it reconstructs the schema, walks each table's b-tree, and for anything the pointer chain can no longer reach it falls back to a raw page sweep that decodes the self-describing records straight out of the leaf pages. It rebuilds the b-trees from scratch around the rows it finds and writes them into a brand-new database you download — the same strategy as SQLite's own .recover command. Rows that can't be attributed to a known table are placed in a lost_and_found table rather than discarded, and if you supply the msgstore.db-wal sidecar its committed frames are overlaid first so the result reflects your last committed messages, not just the last checkpoint.

The honest limits: bytes that were physically overwritten or truncated off the end are gone, and no tool can invent them. Values come back as their on-disk storage class, so a column's affinity may shift. Because the sweep also reads freelist and unvacuumed pages, some previously-deleted messages can resurface. Recovered data is always suspect — SQLite's own docs say so — so verify it against a known-good source before relying on it. And the media blobs still live in the separate Media folder; the database gives you the text and the references, not the pictures themselves.

Why do this in the browser? A chat database is the single worst file to hand to a server you don't control — it can hold every message, phone number and timestamp you've ever exchanged. Upload-based "repair" tools copy that file onto infrastructure you can't inspect, under retention terms you didn't write. Here the file is read from your disk and rebuilt in your tab; you can open the Network panel and confirm 0 bytes of the database leave your machine.

What this can and can't fix

Can fix

  • "Database disk image is malformed" (SQLITE_CORRUPT 11) from a damaged page or a broken b-tree pointer
  • "File is not a database" when only the 16-byte header magic was mangled and the pages behind it survive
  • A msgstore.db torn or half-checkpointed by copying it off the phone while WhatsApp was still open
  • Truncated databases — every message row on a surviving page is pulled out, plus uncheckpointed rows from a supplied -wal sidecar
  • Rows on pages the pointer chain can no longer reach, recovered by a raw page scan into lost_and_found

Can't fix

  • Encrypted .crypt14 / .crypt15 backups without the key — they're ciphertext with no SQLite header and must be decrypted first
  • Messages physically overwritten or truncated off the end of the file — those bytes no longer exist
  • The photos, videos and voice notes themselves (they're separate files in the Media folder, not in the DB)
  • A guarantee that every recovered message is complete or correct — verify recovered data against a known-good source
  • 0-byte files, or a database whose header and pages are all noise (that's a storage-recovery problem first)

If a repair fails, we tell you why (missing data versus broken structure), and you are never charged for a failed repair.

FAQ

WhatsApp says "database disk image is malformed". Are my chats gone?

Usually not. That's SQLite's SQLITE_CORRUPT (code 11): it means the engine hit one inconsistent page or pointer and refused the whole file, not that your messages were erased. The message rows are almost always still sitting in their leaf pages. Walking the file page by page and rebuilding a fresh database around the rows that decode usually brings the history back.

I only have a .crypt14 / .crypt15 backup — can you recover that?

Not directly. A .crypt14 or .crypt15 file is AES-GCM encrypted and has no SQLite header, so it reads as pure noise until it's decrypted back to a plain msgstore.db using WhatsApp's key (or, for crypt15, your 64-digit end-to-end backup key). Once you have the decrypted msgstore.db, drop it here and recovery runs on it.

Will I get my photos and videos back too?

The database holds message text, timestamps and file references — not the media itself. Photos, videos and voice notes are stored as separate files in WhatsApp's Media folder, with only small thumbnails kept inside the DB. Recovering msgstore.db restores the conversation and the pointers to media; the media files are recovered from that folder separately.

I have a msgstore.db-wal file next to the database. Does it matter?

Yes — often a lot. WhatsApp runs in WAL mode, so your newest committed messages can live only in the msgstore.db-wal sidecar until they're checkpointed. Keep it and add it alongside the main .db: its committed frames are overlaid before the scan, so the recovered database reflects your last committed transaction rather than the last checkpoint.

Is my chat database uploaded to be repaired?

No. The file is read from your disk and rebuilt in your browser tab; nothing is transmitted. A chat database is the last file you'd want on someone else's server — it can hold every message and number you've exchanged — so you can open the Network panel and confirm 0 bytes of the database leave your machine.

Related: Repair any SQLite database · Repair a corrupted WhatsApp video · Verify the zero-upload claim