SQLite database disk image is malformed – quick fix
Quick fix for SQLite 'database disk image is malformed' error. Dump and restore, or use integrity check.
Yeah, that error is a gut punch. You're trying to open a database and SQLite just says 'database disk image is malformed.' I've seen it kill a whole morning for a client who lost a day's work in their inventory system. But don't panic – here's the fix that works 90% of the time.
The fix: dump and restore
Open a terminal (or Command Prompt on Windows). Run this:
sqlite3 corrupted.db .dump | sqlite3 fixed.db
If you don't have SQLite3 installed, grab it from sqlite.org or use apt install sqlite3 on Linux. On Mac, it's already there. On Windows, download the command-line tools.
That one-liner reads the corrupted file line by line and writes a fresh copy to fixed.db. It skips corrupted pages and recovers everything it can. I've seen this salvage databases that wouldn't open at all.
Why this works
SQLite stores data in pages. When one page gets garbled – maybe from a power loss during a write, or a bad SSD sector – the whole database refuses to open. The .dump command reads each table row by row, skipping the damaged page. It's like copying a book by hand, leaving out the torn page, and binding a new copy. The new file has no corruption markers.
Had a client last month whose entire print queue database died because of a sudden power outage. Dump and restore brought back 98% of the records. The missing 2% were in the corrupted page – not ideal, but way better than starting from zero.
If dump fails entirely
Sometimes .dump itself throws errors. That's when the corruption is deep – maybe the table schema is damaged. Try this next:
.mode insert
.output dump.sql
.dump
.exit
Then manually edit dump.sql to remove lines that cause syntax errors. Then re-create the database:
sqlite3 fixed.db < dump.sql
If even that fails, you can try extracting individual tables with a custom script. I once wrote a Python script that read the raw bytes and pulled out table names – it's ugly, but it can work when SQLite itself chokes.
Check integrity first
Before you do anything, run this to confirm the corruption:
sqlite3 corrupted.db "PRAGMA integrity_check;"
It'll say 'ok' if clean, or list errors. If it shows 'malformed database' or 'rowid out of order', you're in the right place.
Variation: foreign key mismatch after recovery
After dump-and-restore, you might get foreign key errors. That's because dumped tables come out in arbitrary order. Fix it by running PRAGMA foreign_keys = OFF; before the restore, then turn it back on:
sqlite3 fixed.db "PRAGMA foreign_keys = OFF;"
sqlite3 fixed.db < dump.sql
sqlite3 fixed.db "PRAGMA foreign_keys = ON;"
Prevention so this doesn't happen again
- Use WAL mode:
PRAGMA journal_mode=WAL;– it's much more tolerant of crashes. I set this on every new database I create. - Backup regularly: Even a daily SQL dump to a separate drive saves your bacon. Automate it with a cron job or Task Scheduler.
- Don't kill the process: If your app hangs, don't force-close it while it's writing. Wait a few seconds.
- Use a UPS: Power loss is the #1 cause of corruption in my experience. A $40 uninterruptible power supply is cheap insurance.
- Check disk health: Bad sectors can corrupt any file. Run
chkdsk /fon Windows orfsckon Linux quarterly.
One more thing: if you're using SQLite in a multi-user app, switch to a proper client-server database. SQLite is great for single-user or read-heavy loads, but concurrent writes are asking for trouble. I've seen it happen.
Was this solution helpful?