How to fix SQLITE_IOERR: Some kind of disk I/O error occurred in SQLite

SQLiteINTERMEDIATEHIGHUpdated Dec 22, 2025ยท 360 views

The SQLITE_IOERR error indicates the operating system encountered an I/O error while reading or writing database files. This typically stems from file permissions, filesystem issues, or hardware problems rather than insufficient disk space.

Quick fix

Fixes SQLITE_IOERR

# Check permissions on database file
ls -l /path/to/database.db

# Check directory permissions
ls -ld /path/to/

# Ensure write access to directory (needed for journal files)
chmod 755 /path/to/
chmod 644 /path/to/database.db

# If using WAL mode, check for -wal and -shm files
ls -l /path/to/database.db-wal
ls -l /path/to/database.db-shm
  1. Check file and directory permissions
  2. Enable extended error codes for diagnosis
  3. Run filesystem integrity checks
  4. Verify filesystem compatibility
sqlite โ€” error
# Check permissions on database file
ls -l /path/to/database.db
# Check directory permissions
ls -ld /path/to/
# Ensure write access to directory (needed for journal files)
chmod 755 /path/to/
chmod 644 /path/to/database.db
# If using WAL mode, check for -wal and -shm files
ls -l /path/to/database.db-wal
ls -l /path/to/database.db-shm
SQLITE_IOERR: Some kind of disk I/O error occurred

What this error means

The SQLITE_IOERR error (error code 10) occurs when SQLite cannot complete an operation because the operating system reported an I/O error. This is a generic error code that covers various disk-related failures detected at the OS level. Unlike SQLITE_FULL which specifically indicates a full disk, SQLITE_IOERR suggests problems with the underlying filesystem, file permissions, or hardware. The error often occurs during read, write, or fsync operations on the database file or its associated journal/WAL files. SQLite provides extended error codes (like SQLITE_IOERR_READ, SQLITE_IOERR_WRITE, SQLITE_IOERR_FSYNC) that identify the specific I/O operation that failed, helping narrow down the root cause.

Typical symptoms

  • Database operations fail with "disk I/O error" message
  • Application crashes or hangs when accessing SQLite database
  • Error occurs intermittently, often during write operations
  • Journal or WAL files cannot be created or updated
  • Database operations succeed when run with elevated permissions
  • Error appears after filesystem becomes unmounted or experiences issues

Common causes

  1. Insufficient file permissions on database, journal, or WAL files
  2. Database directory lacks write permissions for creating temporary files
  3. Filesystem became unmounted or disconnected while database was open
  4. Network filesystem (NFS, CIFS) connection issues or locking problems
  5. Hardware failure or bad disk sectors on storage device
  6. Filesystem corruption affecting database file region
  7. Antivirus or security software blocking file access
  8. Database file opened by another process with exclusive lock
  9. Incompatible filesystem type (some F2FS configurations)
  10. SELinux or AppArmor policies restricting file access

How to fix "SQLITE_IOERR: Some kind of disk I/O error occurred"

1Check file and directory permissions

Verify that your application has read and write access to the database file, its directory, and any journal/WAL files:

bash
# Check permissions on database file
ls -l /path/to/database.db

# Check directory permissions
ls -ld /path/to/

# Ensure write access to directory (needed for journal files)
chmod 755 /path/to/
chmod 644 /path/to/database.db

# If using WAL mode, check for -wal and -shm files
ls -l /path/to/database.db-wal
ls -l /path/to/database.db-shm

The database directory must be writable because SQLite creates temporary journal and lock files during transactions.

2Enable extended error codes for diagnosis

Get more specific error information by enabling SQLite extended result codes:

c
// C API
sqlite3_extended_result_codes(db, 1);
int extended_code = sqlite3_extended_errcode(db);
python
# Python sqlite3
import sqlite3
conn = sqlite3.connect('database.db')
# Extended codes are enabled by default in Python
try:
    conn.execute("...")
except sqlite3.OperationalError as e:
    print(f"Error: {e}")
javascript
// Node.js better-sqlite3
const Database = require('better-sqlite3');
const db = new Database('database.db');
// Check error.code property for extended codes

Extended codes like SQLITE_IOERR_READ (266), SQLITE_IOERR_WRITE (778), or SQLITE_IOERR_FSYNC (1034) help identify which operation failed.

3Run filesystem integrity checks

Check for filesystem corruption that might affect the database:

bash
# Linux: Check filesystem (unmount first if possible)
sudo fsck /dev/sdX1

# Check disk health with SMART
sudo smartctl -a /dev/sdX

# For mounted filesystems, check dmesg for I/O errors
dmesg | grep -i "i/o error"
dmesg | grep -i "sector"

# Check database file integrity
sqlite3 database.db "PRAGMA integrity_check;"

If integrity_check reports corruption, you may need to recover from a backup or use the .recover command.

4Verify filesystem compatibility

Some network filesystems and exotic filesystem types can cause issues:

bash
# Check filesystem type
df -T /path/to/database.db

# Avoid SQLite on network filesystems when possible
# NFS/CIFS have locking and caching issues

Network filesystem workarounds:

1. Copy database to local filesystem before accessing
2. Use SQLite's shared memory and WAL mode carefully
3. Consider using a database server (PostgreSQL/MySQL) instead

For F2FS filesystems, ensure you're using a recent kernel version as older versions had compatibility issues.

5Check for file locking conflicts

Ensure no other process has an exclusive lock on the database:

bash
# Linux: Find processes with file open
lsof /path/to/database.db

# Check for stuck lock files
ls -la /path/to/database.db-journal
rm /path/to/database.db-journal  # Only if no other process is using it

# For WAL mode
ls -la /path/to/database.db-wal
ls -la /path/to/database.db-shm

If lock files exist when no process is using the database, they may be stale and can be removed.

6Check antivirus and security software

Antivirus, EDR, or security software may interfere with database file access:

bash
# Temporarily disable antivirus to test (Linux with ClamAV)
sudo systemctl stop clamav-daemon

# Check SELinux denials
sudo ausearch -m avc -ts recent

# Check AppArmor denials
sudo journalctl | grep DENIED

If security software is the cause, add exceptions for your database directory or SQLite process.

For Deep Security or similar EDR tools, check vendor documentation for SQLite-specific exclusions.

7Test with minimal database configuration

Create a test database to isolate the issue:

bash
# Create test database in /tmp
sqlite3 /tmp/test.db "CREATE TABLE test(id INTEGER PRIMARY KEY, data TEXT);"
sqlite3 /tmp/test.db "INSERT INTO test(data) VALUES('test');"
sqlite3 /tmp/test.db "SELECT * FROM test;"

If the test succeeds:
- The issue is specific to your database file or location
- Try moving the original database to a different location
- Check if the original database file is corrupted

If the test fails:
- The issue is systemic (permissions, filesystem, hardware)
- Check system logs and disk health

Advanced notes

Extended Error Code Reference:

SQLite provides over 20 extended IOERR codes. Key ones include:
- SQLITE_IOERR_READ (266): Read operation failed
- SQLITE_IOERR_WRITE (778): Write operation failed
- SQLITE_IOERR_FSYNC (1034): Flush/sync operation failed
- SQLITE_IOERR_ACCESS (3338): File access permissions issue
- SQLITE_IOERR_LOCK (3850): File locking operation failed
- SQLITE_IOERR_CORRUPTFS (8458): Filesystem corruption detected

Network Filesystem Considerations:

SQLite's official documentation warns against using network filesystems due to locking inconsistencies and caching issues. NFS and CIFS can cause false "disk I/O error" reports when file locking protocols fail. If you must use network storage, consider:
- Mounting with nolock option (disables locking - use with caution)
- Using SQLite in WAL mode with PRAGMA locking_mode=EXCLUSIVE
- Implementing application-level locking instead of relying on filesystem locks
- Using a proper client-server database instead

Journal Mode Impact:

Different journal modes have different I/O patterns:
- DELETE mode (default): Creates and deletes journal files frequently
- WAL mode: Maintains persistent -wal and -shm files
- MEMORY mode: Reduces disk I/O but loses crash recovery

If you encounter I/O errors with WAL mode, switching to DELETE mode may help diagnose whether the issue is with the main database file or auxiliary files.

Recovery from Corruption:

If integrity_check reveals corruption, recovery options include:

bash
# Dump recoverable data
sqlite3 corrupted.db ".recover" | sqlite3 recovered.db

# Or use .dump for schema and data
sqlite3 corrupted.db ".dump" | sqlite3 new.db

The .recover command (SQLite 3.32+) is more robust than .dump for corrupted databases.

Frequently asked questions

What does "SQLITE_IOERR" mean?
The SQLITE_IOERR error (error code 10) occurs when SQLite cannot complete an operation because the operating system reported an I/O error. This is a generic error code that covers various disk-related failures detected at the OS level. Unlike SQLITE_FULL which specifically indicates a full disk, SQLITE_IOERR suggests problems with the underlying filesystem, file permissions, or hardware.
How do I fix "SQLITE_IOERR"?
The SQLITE_IOERR error indicates the operating system encountered an I/O error while reading or writing database files. This typically stems from file permissions, filesystem issues, or hardware problems rather than insufficient disk space.
What causes "SQLITE_IOERR"?
Insufficient file permissions on database, journal, or WAL files Database directory lacks write permissions for creating temporary files Filesystem became unmounted or disconnected while database was open
Is the "SQLITE_IOERR" error serious?
Yes. This is a high-severity error that usually blocks work until it is fixed, but the steps above resolve it.

Official resources & further reading