database disk image is malformed
Production Risk
SQLITE_CORRUPT is a critical production incident. Stop all writes immediately to prevent further damage. Copy the .db and any .db-wal / .db-shm sidecar files before any recovery attempt. A corrupted WAL file alongside an intact main database is recoverable by deleting the WAL, but only if the application can tolerate losing the uncommitted WAL data.
SQLITE_CORRUPT (result code 11) means SQLite detected structural inconsistency within the database file itself — invalid B-tree pointers, mismatched page counts, or an unrecognised file format. This is one of the most serious errors because it means some or all of the data in the database may be unreadable or silently wrong.
- 1The database file was truncated or partially overwritten by another process
- 2Hardware or filesystem corruption (failing storage, power loss during an fsync, NFS write ordering issues)
- 3The WAL file and the main database file are from different checkpoints (file swap or copy error)
- 4The file was intentionally or accidentally edited as a binary file
- 5Using SQLite on a filesystem that does not honour fsync (certain NFS or tmpfs configurations)
A database file header is manually zeroed, simulating corruption.
import sqlite3
# Corrupt the file header (first 16 bytes)
with open('demo.db', 'r+b') as f:
f.write(b'\x00' * 16)
conn = sqlite3.connect('demo.db')
conn.execute('SELECT * FROM t') # triggers SQLITE_CORRUPTexpected output
sqlite3.DatabaseError: database disk image is malformed
Fix 1
Restore from a known-good backup
WHEN When a verified backup exists — the only fully reliable fix.
import shutil
shutil.copy('backup_20240101.db', 'production.db')Why this works
Corruption in a SQLite file cannot be reliably repaired in-place. The correct response is to restore from the most recent backup that passes PRAGMA integrity_check.
Fix 2
Attempt data recovery with sqlite3 .recover
WHEN When no backup exists and partial data recovery is better than nothing.
# In the sqlite3 CLI: sqlite3 corrupted.db ".recover" | sqlite3 recovered.db # Then verify: sqlite3 recovered.db "PRAGMA integrity_check"
Why this works
The .recover dot-command (available in the CLI from SQLite 3.29.0+) scans the raw pages of the database file and attempts to reconstruct tables and data, skipping pages it cannot parse. It will not recover data from unreadable pages.
✕ Run VACUUM on a corrupt database hoping it will fix it
VACUUM reads every page and writes a new file; on a corrupt database it will either fail with another SQLITE_CORRUPT or silently drop the unreadable data, potentially losing more rows than a targeted recovery would.
.recover dot-command introduced in the CLI for partial data salvage from corrupt files.
SQLITE_CORRUPT_VTAB (267) extended code added for virtual table corruption distinct from B-tree corruption.
sqlite3.h — SQLITE_CORRUPT = 11
How to recover a corrupt SQLite database ↗PRAGMA integrity_check ↗Content generated with AI assistance and reviewed for accuracy. Found an error? hello@errcodes.dev