Repair a Corrupted Database thumbnail

How to Repair a Corrupted SQLite Database

SQLite is very reliable. But files can still get damaged. A crash at the wrong moment, a failing disk, a bad copy, or deleting the wrong side file can leave a database that won’t work properly.

The classic sign is the error “database disk image is malformed.” Queries fail halfway through, or the app that uses the database crashes.

This guide walks you through repairing a corrupted SQLite database step by step. You’ll learn how to check how bad the damage is, how to recover as much data as possible, and how to avoid corruption in the future. Most of the time, you can save nearly everything.

Before you touch anything: make a copy

This is the most important step. Recovery tools read the damaged file, but mistakes happen. Protect what you have.

  1. Close every app that uses the database.
  2. Copy the database file to a new folder.
  3. Copy any -wal, -shm and -journal files with the same name too. Keep the names exactly the same.
  4. Work only on the copies.

The -wal file is especially important. It may contain recent changes that haven’t reached the main file yet. Deleting it can make things worse.

Signs of a corrupted SQLite database

You might see one or more of these:

  • “database disk image is malformed” (error code 11, SQLITE_CORRUPT)
  • “file is not a database” (the header itself is damaged)
  • Queries that work on some tables but fail on others
  • Missing rows that you know existed
  • An app that crashes whenever it opens its data

If you’re seeing “file is not a database,” check our guide to that specific error first. It’s often encryption or a bad copy rather than corruption.

Step 1: Check the damage with integrity_check

SQLite has a built-in health check. Open the copy with the sqlite3 command-line tool and run:

PRAGMA integrity_check;

If the database is healthy, it returns a single word:

ok

If not, it lists the problems it found, such as pages that are missing or rows that don’t match their indexes.

For a faster but less thorough check, use:

PRAGMA quick_check;

Don’t have sqlite3 installed? Our guides for Windows and Mac show how to get it. You can also run these PRAGMA commands in the Run SQL tab of our online SQLite viewer, as long as the file opens at all.

Step 2: Try the easy fixes first

Some damage is only in indexes, not in your actual data. Indexes can be rebuilt from scratch.

If integrity_check mentions errors like “row missing from index” or “wrong number of entries in index,” try:

REINDEX;
PRAGMA integrity_check;

If the check now says ok, you’re done. Keep a backup of the original anyway.

You can also try making a clean copy of the database:

VACUUM INTO 'clean.db';

This writes a fresh, compact database. It only works if SQLite can still read all the data. If it fails with an error, move on to the next step.

Step 3: Recover data with .recover

The sqlite3 command-line tool has a special command built for damaged databases. It reads every page it can and rebuilds the data as SQL statements.

Run it like this from your terminal (not inside the sqlite3 prompt):

sqlite3 broken.db ".recover" > recovered.sql

Then build a new database from the output:

sqlite3 fixed.db < recovered.sql

Or do both in one line:

sqlite3 broken.db ".recover" | sqlite3 fixed.db

Now check the new file:

sqlite3 fixed.db "PRAGMA integrity_check;"

What about the lost_and_found table?

Sometimes .recover finds rows but can’t tell which table they belonged to. It puts them in a table called lost_and_found. Open it and look. You can often match the rows to their original tables by the number and type of columns.

The .recover command needs a reasonably recent sqlite3. If your version doesn’t know it, download the latest tools from sqlite.org.

Step 4: Try .dump if .recover isn’t available

The older approach is .dump, which exports the database as SQL:

sqlite3 broken.db ".dump" > dump.sql
sqlite3 fixed.db < dump.sql

.dump stops at errors more easily than .recover, so it usually saves less data. But it’s worth trying if .recover isn’t an option.

If the dump ends with a line like ROLLBACK; because of an error, open dump.sql in a text editor and change that last line to COMMIT; before importing. That keeps everything that was exported before the error.

Step 5: Save what you can table by table

If a full recovery fails, try pulling out one table at a time. Open the damaged copy in our online viewer or the sqlite3 shell and run:

SELECT * FROM customers;

If it works, export the result as CSV right away. Then try the next table. Even if some tables are badly damaged, others may be perfectly readable. Our SQLite to CSV guide shows how to export quickly.

Step 6: Check the results

After any recovery:

  1. Run PRAGMA integrity_check; on the new file. It should say ok.
  2. Compare row counts between the old and new files for each table.
  3. Open the most important tables and look at recent rows.
  4. Test the new file with the app that uses it. Make sure the app is closed while you swap files, and keep the old files as backups.

For a quick way to compare tables and row counts, see how to list all tables in SQLite.

A worked example

Here’s a typical case. A small business keeps its orders in shop.db. After a power cut, the app shows “database disk image is malformed.”

  1. The owner closes the app and copies shop.db and shop.db-wal into a folder called rescue.
  2. Running PRAGMA integrity_check; lists several errors on one index and a few damaged pages.
  3. REINDEX fixes the index errors, but the page errors remain.
  4. Running sqlite3 shop.db ".recover" | sqlite3 fixed.db builds a new database.
  5. PRAGMA integrity_check; on fixed.db returns ok.
  6. Comparing row counts shows the orders table lost 3 rows out of 12,400. A lost_and_found table holds 3 rows with the same column count as orders. They’re the missing orders.
  7. The owner inserts those rows back into orders, checks the app, and keeps rescue as a backup.

Total time: about fifteen minutes. That’s a normal outcome. Full recovery, or very close to it, is common when you act quickly and work on copies.

When recovery isn’t possible

Sometimes the damage is too deep:

  • Overwritten data. If other data was written over the damaged pages, the old content is gone.
  • Encrypted and damaged. Recovery tools can’t read encrypted pages without the key.
  • Missing large parts of the file. A truncated copy loses everything past the cut.

In these cases, your best bet is a backup. Check cloud backups, older copies on other devices, or app-level exports.

What causes SQLite corruption?

SQLite is designed to survive crashes and power cuts. Real corruption usually comes from outside SQLite:

CauseHow it damages the file
Deleting -wal or -journal filesLoses changes or undo information SQLite needs
Copying a live databaseThe copy catches a half-written state
Network drives (NFS, SMB)Broken file locking lets two writers collide
Failing disks or bad memoryBits flip on storage or in transit
Disabling safety settingsPRAGMA synchronous = OFF can lose data on power loss
Buggy software writing to the file directlyBypasses SQLite’s safeguards

How to prevent corruption

  • Never delete -wal, -shm or -journal files while the database might need them.
  • Close apps before copying their databases, or use the sqlite3 .backup command, which makes a consistent copy of a live database.
  • Keep databases on local disks, not network shares.
  • Leave safety settings on. Don’t turn off synchronous writes unless you truly accept the risk.
  • Back up regularly. A daily copy made with .backup or VACUUM INTO is cheap insurance.
  • Watch for disk warnings. Corruption is often an early sign of failing hardware.

If you often see locking errors too, our guide to the database is locked error explains safe fixes.

Want the technical detail? See the official SQLite guide to recovering a corrupt database.

Frequently asked questions

Can I repair a SQLite database online?

You can check and export data from a damaged file in our browser viewer if it still opens. For full recovery, use the sqlite3 command line and its .recover command.

Will .recover change my original file?

No. It only reads the damaged file. It writes the recovered SQL to the output you choose.

What does “database disk image is malformed” mean?

SQLite found data structures inside the file that don’t make sense. Part of the file is damaged.

Is it safe to use the recovered database?

After integrity_check says ok and you’ve compared row counts, yes. Keep the damaged original as a backup in case you notice missing data later.

Summary

To repair a corrupted SQLite database, copy it first with its side files, run PRAGMA integrity_check, try REINDEX and VACUUM INTO for light damage, then use .recover to rebuild everything else into a new file. Export anything you can’t recover table by table. For quick checks and exports without installing tools, open the file in our free SQLite viewer.

Similar Posts