attempt to write a readonly database
This error occurs when SQLite can't write to the database file due to file permissions, the file being on a read-only filesystem, or the connection being opened in read-only mode.
The readonly database error means SQLite can write to the database file. This is usually a file system permission issue.
Understanding the Error
SQLite successfully opened the database but can't perform write operations (INSERT, UPDATE, DELETE, CREATE).
Common Causes
1. File Permissions
The database file or its directory doesn't allow writes:
2. Directory Not Writable
SQLite needs to create journal files in the same directory:
3. Read-Only Filesystem
The filesystem itself might be mounted read-only:
- Docker containers with read-only mounts
- Network drives
- SD cards with write protection
4. Connection Opened Read-Only
Your code explicitly opened a read-only connection:
5. Database Opened by Another Process
Another process might have an exclusive lock.
6. File Owned by Different User
Web servers often run as a different user:
How to Fix It
Solution 1: Fix File Permissions
Solution 2: Fix Directory Permissions
SQLite needs to write journal files:
Solution 3: Change File Ownership
Match the user running your application:
Solution 4: Check Docker Volume Mounts
Solution 5: Use a Writable Location
Move the database to a writable directory:
Solution 6: Open in Read-Write Mode
Ensure you're not accidentally opening read-only:
Solution 7: Check for WAL Files
If using WAL mode, these files also need write access:
Debugging Steps
1. Check Current Permissions
2. Test Write Access
3. Check Process User
4. Check Filesystem
Platform-Specific Issues
Linux/Mac
Docker
Serverless/Lambda
Best Practices
- Store databases in data directories, not application directories
- Set appropriate permissions during deployment
- Document required permissions in your setup guide
- Use environment variables for database paths
- Test write access on application startup
Related Errors
- SQLITE_CANTOPEN - Can't open the database file at all
- SQLITE_BUSY - Database is locked by another connection
- SQLITE_IOERR - General I/O error