Database corruption¶
SQLite reports corruption as SQLite Error 11: 'database disk image is malformed'. It means the database file itself (/config/db.sqlite) is damaged — it is not a bug in a specific query, and retrying never heals it.
Symptoms¶
- Repeating log lines such as
Error processing blob cleanup queue. Reason: Database file is corrupt ...from background services. - A startup integrity check failure since 1.1.0: after migrations, the backend runs
PRAGMA quick_checkon the main database and logs an Error with recovery guidance when the file is damaged. Startup deliberately continues so you can still reach the restore UI. - WebDAV listings, queue, or history views failing or returning stale data.
Causes¶
Corruption is almost always environmental:
/configon a network filesystem (SMB/NFS) that does not honor SQLite's locking andfsyncrequirements — the most common cause.- Unclean shutdowns: container killed mid-write (
docker kill, OOM killer, power loss). - Failing or full storage underneath
/config.
InfiniDysk runs SQLite in WAL mode with synchronous=NORMAL, which mitigates but cannot prevent corruption on filesystems that lie about durability.
Recovery¶
Restore from a backup (recommended)¶
Use the guided restore under Settings → Backup & Restore — see Backup and restore. Restore replaces settings, queue, history, and WebDAV tree metadata, creates a pre-restore safety backup, and restarts into maintenance. Blobs under /config/blobs/ are not part of SQL dumps; missing blobs are reported in the UI after the restore.
If you do not have a backup, enable daily backups after recovering so the next incident is a one-click restore.
Advanced: salvage with the SQLite CLI¶
On a copy of the file, with the container stopped:
.recover extracts whatever rows are still readable into a fresh database. Expect partial data loss: rows on damaged pages are skipped. Point /config at the recovered file only after verifying it opens cleanly (PRAGMA integrity_check should print ok).
Last resort: fresh start¶
Stop the container, move db.sqlite* aside, and start again. A fresh database loses settings, queue, history, and the WebDAV tree metadata (the content itself lives on Usenet and can be re-added).
Prevention¶
- Keep
/configon local disk, not a network share. - Enable daily backups with a retention count under Settings → Backup & Restore.
- Stop the container gracefully (
docker stop, notdocker kill) so SQLite can checkpoint the WAL.