← Debugging Guides

阅读中文版本

SQLite "file is not a database" — Corrupt or Wrong File

Fix "file is not a database" by checking the SQLite magic header, ruling out an HTML error page or wrong path, and restoring from backup.

beginnerdebuggingsqlitecorruptionfilesystem

Symptoms

  • SQLite error: "file is not a database" when opening a path
  • The file was recently downloaded or restored
  • The app creates a zero-byte file then fails to read it

Possible causes

  • The file is not SQLite at all (an HTML error page saved as .db, or a different format)
  • The path is wrong and points at an unrelated existing file
  • The database header is corrupt from an interrupted write or disk issue

Diagnosis steps

Inspect the file header

head -c 16 app.db | xxd

Interpretation

A valid SQLite file begins with the magic string "SQLite format 3\0"; anything else is not SQLite.

Check size and path

ls -l app.db && file app.db

Interpretation

A zero-byte or HTML file reveals a wrong path or a failed download.

Root cause

SQLite identifies a database by the 16-byte magic header. If that header is absent—because the file is HTML, a different format, empty, or corrupted—opening it as a database fails with "file is not a database".

Fix

Point at the correct path, ensure the file is a real SQLite database, validate the header before use, and if corruption is confirmed restore from backup and check the filesystem.

Risk note

Attempting to recover a corrupt database by deleting and recreating it loses data; back up the damaged file first.

Verify the fix

Open the correct file and confirm PRAGMA integrity_check returns ok; assert the header matches the magic string.

Symptoms

When you hit “SQLite “file is not a database” — Corrupt or Wrong File”, guessing wastes time. The guide below follows evidence: reproduce the symptom, run targeted diagnostics, identify the root cause, apply the fix, and verify it with concrete checks.

Observed symptoms include:

  • SQLite error: “file is not a database” when opening a path
  • The file was recently downloaded or restored
  • The app creates a zero-byte file then fails to read it

Reproduce and Diagnose

Reproduce the failure in isolation before changing any code. Work through the checks below in order; each one narrows the search space.

Step 1: Inspect the file header

head -c 16 app.db | xxd

A valid SQLite file begins with the magic string “SQLite format 3\0”; anything else is not SQLite.

Step 2: Check size and path

ls -l app.db && file app.db

A zero-byte or HTML file reveals a wrong path or a failed download.

Likely contributors, in order of frequency:

  • The file is not SQLite at all (an HTML error page saved as .db, or a different format)
  • The path is wrong and points at an unrelated existing file
  • The database header is corrupt from an interrupted write or disk issue

Root Cause

SQLite identifies a database by the 16-byte magic header. If that header is absent—because the file is HTML, a different format, empty, or corrupted—opening it as a database fails with “file is not a database”.

The Fix

Point at the correct path, ensure the file is a real SQLite database, validate the header before use, and if corruption is confirmed restore from backup and check the filesystem.

Watch out: Attempting to recover a corrupt database by deleting and recreating it loses data; back up the damaged file first.

# verify the magic header before opening
head -c 16 app.db | xxd
# expected: 5351 4c69 7465 2066 6f72 6d61 7420 3300  (

# integrity check after opening
sqlite3 app.db 'PRAGMA integrity_check;'

# recover from a good backup rather than recreating
cp app.db.bak app.db

Verify and Prevent

Open the correct file and confirm PRAGMA integrity_check returns ok; assert the header matches the magic string.

Once verified, add a regression test that reproduces the original symptom so the failure cannot silently return.

This class of failure is usually environmental rather than pure logic, so capture the exact command, the environment variables, and the working directory in your bug report. Reproduce it in the smallest possible script, then widen the scope only once the minimal case is understood. A short written checklist for this failure mode saves hours the next time it appears.