SQLite “file is not a database”: check the file before repairing it

This error means SQLite could not interpret the file as a database. It does not establish whether the file is encrypted, the wrong format, or damaged.

1. Check that you opened the intended file

ls -lh "/path/to/database.db"
file "/path/to/database.db"
hexdump -C -n 16 "/path/to/database.db"

A download might be an HTML error response or a ZIP archive with the wrong extension. A .db file may belong to another database engine. Select the main SQLite file, not its WAL or SHM companion.

2. Look for the SQLite header

An ordinary nonempty SQLite 3 database starts with SQLite format 3 and a zero byte. Missing this header is a clue, not a complete diagnosis. An encrypted file can hide it; a damaged header can destroy it. A zero-byte file can also be an empty SQLite database, so file size alone does not prove corruption. See the file-format reference.

3. Check for encryption

If the producing application uses SQLCipher or another encryption extension, use the matching engine, settings and key. Ordinary sqlite3 and Petti 1 cannot decrypt that file. Renaming it to .sqlite does not change its format.

4. Test a known SQLite copy

Preserve the original and any companion files. If the source is active, obtain a consistent backup rather than copying files during writes. On a known SQLite copy that opens, you can run an explicit check:

sqlite3 -readonly "/path/to/snapshot.sqlite" 'PRAGMA quick_check;'

ok means this check found no errors; it is not an exhaustive application-data validation. The check can take substantial time on a large file. If the header cannot be read, it may fail before checking pages. See SQLite’s quick_check documentation.

Choose the next step from the evidence

Use the creating application for a non-SQLite format, the correct encryption-aware tool for an encrypted database, or a known-good backup for damaged data. Recovery commands should work on disposable copies, not your only original. SQLite distinguishes SQLITE_NOTADB from SQLITE_CORRUPT in its result codes, though the error text alone may not reveal the underlying cause.