Suppose your read-only connection to the database executed a SELECT which returned a thousand rows. You would need to know that another connection to the database didn't change the database part way through the rows being read. So even a read-only connection to the database needs to be able to tell other connections that it is in use. A WAL database requires two other files to maintain a record of locking and changes. Even if you open the file telling SQLite you need read-only access, SQLite still has to create the -shm and -wal files in the same folder as the database file. So it still needs write permission to that folder. You might be able to get a result by having another connection create the -shm and -wal files first, then establishing your read-only connection. But that's a hack and I don't know if it will really work.