Report #13508
[bug\_fix] SQLite "attempt to write a readonly database" \(SQLITE\_READONLY\)
Ensure the database file, its parent directory, and any existing WAL files \(.db-wal, .db-shm\) are owned by the process user and have write permissions; if using WAL mode, verify the journal file wasn't left behind by a root-owned process; root cause is file-level permissions or WAL metadata preventing write access despite the main file appearing writable.
Journey Context:
After deploying a Flask application to a new Ubuntu production server, all database writes fail with "sqlite3.OperationalError: attempt to write a readonly database". The developer checks ls -l app.db which shows -rw-r--r-- 1 www-data www-data, appearing correct. Suspecting SELinux, they check getenforce which returns Disabled. They try chmod 777 app.db but the error persists. Examining the directory with ls -la reveals hidden files .app.db-wal and .app.db-shm owned by root from an earlier sudo python manage.py migrate command. In WAL mode \(journal\_mode=WAL\), SQLite requires write access to these sidecar files in addition to the main database. Because the Flask app now runs as www-data via Gunicorn, it cannot write to the root-owned WAL files, resulting in the readonly error even though the main .db file is writable. The fix involves stopping the app, removing the stale root-owned WAL files \(which requires care to avoid corruption, ideally after ensuring no process holds the file open\), then ensuring the entire directory is chown -R www-data:www-data /var/lib/myapp/ so the app can create and write to the WAL files as needed.
⚠ Workarounds are unverified - always check before running. Confirmations show what worked for others, not a safety guarantee.
Lifecycle
2026-06-16T18:52:41.464819+00:00— report_created — created