SQLite: attempt to write a readonly database (tested)

sqlite3.OperationalError: attempt to write a readonly database looks like a simple file-permission problem — and often is, but not always. We reproduced it two genuinely different ways and measured that both give the exact same error text.

1. The obvious cause: the database file itself is read-only

We created a database, then removed write permission from the file:

$ chmod 444 ro.db
con = sqlite3.connect("ro.db")
con.execute("INSERT INTO t VALUES (1)")
sqlite3.OperationalError: attempt to write a readonly database

Restoring write permission on the file (chmod 644 ro.db) fixed it immediately with no other change — the next insert and commit succeeded.

2. The non-obvious cause: a read-only containing directory, with the file itself writable

We reset the file to fully writable (chmod 755 db2.db) and instead removed write permission from its directory:

$ chmod 555 /tmp/sq3dir   # the directory, not the .db file
con = sqlite3.connect("/tmp/sq3dir/db2.db")
con.execute("INSERT INTO t VALUES (2)")
sqlite3.OperationalError: attempt to write a readonly database

Why: SQLite's default rollback-journal mode needs to create a temporary journal file (and WAL mode needs its own extra files) in the same directory as the database, so it can roll back on a crash. If the directory itself can't be written to, SQLite can't create that file — even though the .db file's own permissions are fine. The error message doesn't distinguish the two cases: it's identical either way.

3. The fix: check both permissions, not just the file's

We confirmed checking only the database file's permissions can be misleading. The full check is:

ls -l mydb.db          # check the file
ls -ld "$(dirname mydb.db)"   # check its containing directory too

Restoring write permission on whichever one is actually restricted (chmod u+w on the file, or on the directory) resolves it — we confirmed both independently in this test, and that fixing only the file doesn't help if the directory is the real cause.

Frequently asked questions

What does 'attempt to write a readonly database' mean in SQLite?

Either the database file itself lacks write permission, or — less obviously — its containing directory does, even if the file is fully writable. We reproduced both causes independently and confirmed they produce the identical error text.

Why would a directory's permissions affect writing to a file inside it?

SQLite needs to create a temporary journal (or WAL) file in the same directory as the database for crash-safe rollback. We confirmed that if the directory itself isn't writable, this fails with the same 'readonly database' error even though the .db file's own permissions are unrestricted.

If chmod on the .db file doesn't fix it, what should I check next?

The containing directory's permissions — we measured that chmod 755 on the file alone did not help when the directory itself was chmod 555; only restoring write permission on the actual restricted path (file or directory) fixed it.

Does this happen even with a correctly-owned file?

Yes — ownership is separate from permission bits. We used a file owned by the same user running the script in both tests; the read-only permission bit alone (444, or a 555 directory) was sufficient to trigger the error regardless of ownership.

Written with AI assistance. Measured on 2026-10-03 with Python 3.13.5's built-in sqlite3 module and real Unix file permissions (chmod), on a read-only database file and, separately, a writable file inside a read-only directory. Every message below is copy-pasted output, not paraphrased. PlainHeaders is our extension; Python's sqlite3 is built in.