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_READONLY: attempt to write a readonly database
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