[GH-ISSUE #3757] Trying to write in a read only connection #1317

Closed
opened 2026-03-07 21:02:21 +03:00 by kerem · 14 comments
Owner

Originally created by @webysther on GitHub (Sep 18, 2025).
Original GitHub issue: https://github.com/dbeaver/cloudbeaver/issues/3757

Originally assigned to: @HocKu7 on GitHub.

Description

For a read-only connection the sqlite driver try to write the journal in same directory raising this error:

SQL Error [8]: [SQLITE_READONLY_DIRECTORY] Process does not have permission to create a journal file in the 
same directory as the database and the creation of a journal file is a prerequisite for writing (attempt to 
write a readonly database)

Steps to reproduce

  1. Create a SQLite read-only connection in a folder mounted as read-only
  2. Build a SQLite DB with WAL enabled
  3. Trying connect

Expected/Desired Behavior

Read the database normally without trying write in disk

CloudBeaver Version

25

Additional context

No response

Originally created by @webysther on GitHub (Sep 18, 2025). Original GitHub issue: https://github.com/dbeaver/cloudbeaver/issues/3757 Originally assigned to: @HocKu7 on GitHub. ### Description For a `read-only` connection the sqlite driver try to write the journal in same directory raising this error: ```log SQL Error [8]: [SQLITE_READONLY_DIRECTORY] Process does not have permission to create a journal file in the same directory as the database and the creation of a journal file is a prerequisite for writing (attempt to write a readonly database) ``` ### Steps to reproduce 1. Create a SQLite read-only connection in a folder mounted as read-only 2. Build a SQLite DB with WAL enabled 3. Trying connect ### Expected/Desired Behavior Read the database normally without trying write in disk ### CloudBeaver Version 25 ### Additional context _No response_
kerem 2026-03-07 21:02:21 +03:00
Author
Owner

@dariamarutkina commented on GitHub (Sep 19, 2025):

Hello, @webysther ! Thanks for the report🦫

Quick question to align expectations: do you know of any setup where a SQLite DB in WAL mode works from a directory mounted read-only with a read-only connection? Or is this a desired behavior you’d like us to support? Our understanding is that WAL requires write access to create/update the *.db-wal and *.db-shm files next to the database file.

Could you share a minimal repro and environment details?

  • CloudBeaver version/build, deployment (Docker? image tag), OS/filesystem, mount options.
  • SQLite version / JDBC driver version.
  • Exact connection string (e.g., plain path vs file:/…?mode=ro / immutable=1).
  • Whether my.db-wal / my.db-shm exist before connecting.

Possible workarounds meanwhile:

  • If the folder must stay read-only: open with file:/path/my.db?mode=ro&immutable=1, or switch the DB to PRAGMA journal_mode=DELETE (no WAL). Both allow read-only browsing.
  • If WAL is required: mount that directory read-write (or copy the DB to a writable location before connecting), since WAL/shm must live alongside the DB file.

Thank you! 🦫

<!-- gh-comment-id:3311427579 --> @dariamarutkina commented on GitHub (Sep 19, 2025): Hello, @webysther ! Thanks for the report🦫 Quick question to align expectations: do you know of any setup where a SQLite DB in WAL mode works from a directory mounted read-only with a read-only connection? Or is this a desired behavior you’d like us to support? Our understanding is that WAL requires write access to create/update the *.db-wal and *.db-shm files next to the database file. Could you share a minimal repro and environment details? - CloudBeaver version/build, deployment (Docker? image tag), OS/filesystem, mount options. - SQLite version / JDBC driver version. - Exact connection string (e.g., plain path vs file:/…?mode=ro / immutable=1). - Whether my.db-wal / my.db-shm exist before connecting. Possible workarounds meanwhile: - If the folder must stay read-only: open with file:/path/my.db?mode=ro&immutable=1, or switch the DB to PRAGMA journal_mode=DELETE (no WAL). Both allow read-only browsing. - If WAL is required: mount that directory read-write (or copy the DB to a writable location before connecting), since WAL/shm must live alongside the DB file. Thank you! 🦫
Author
Owner

@webysther commented on GitHub (Sep 19, 2025):

Hello, @webysther ! Thanks for the report🦫

Quick question to align expectations: do you know of any setup where a SQLite DB in WAL mode works from a directory mounted read-only with a read-only connection? Or is this a desired behavior you’d like us to support? Our understanding is that WAL requires write access to create/update the *.db-wal and *.db-shm files next to the database file.

Could you share a minimal repro and environment details?

  • CloudBeaver version/build, deployment (Docker? image tag), OS/filesystem, mount options.
  • SQLite version / JDBC driver version.
  • Exact connection string (e.g., plain path vs file:/…?mode=ro / immutable=1).
  • Whether my.db-wal / my.db-shm exist before connecting.

Possible workarounds meanwhile:

  • If the folder must stay read-only: open with file:/path/my.db?mode=ro&immutable=1, or switch the DB to PRAGMA journal_mode=DELETE (no WAL). Both allow read-only browsing.
  • If WAL is required: mount that directory read-write (or copy the DB to a writable location before connecting), since WAL/shm must live alongside the DB file.

Thank you! 🦫

If the option need to be added like ?mode=ro&immutable=1 why not add this option in the path when open the connection when I mark as read-only in the options?

BTW (don't work):

Image
java.sql.SQLException: opening db: '/mnt/jellyfin/jellyfin.db?immutable=1&mode=ro': Permission denied
	at org.sqlite.SQLiteConnection.open(SQLiteConnection.java:271)
	at org.sqlite.SQLiteConnection.<init>(SQLiteConnection.java:67)
	at org.sqlite.jdbc3.JDBC3Connection.<init>(JDBC3Connection.java:28)
	at org.sqlite.jdbc4.JDBC4Connection.<init>(JDBC4Connection.java:19)
	at org.sqlite.JDBC.createConnection(JDBC.java:106)
	at org.sqlite.JDBC.connect(JDBC.java:79)
	at org.jkiss.dbeaver.model.impl.jdbc.JDBCConnectionOpener.run(JDBCConnectionOpener.java:112)
	at org.jkiss.dbeaver.model.impl.jdbc.JDBCConnectionOpener.run(JDBCConnectionOpener.java:86)
	at org.jkiss.dbeaver.model.impl.jdbc.JDBCDataSource.openConnection(JDBCDataSource.java:215)
	at org.jkiss.dbeaver.model.impl.jdbc.JDBCDataSource.openConnection(JDBCDataSource.java:133)
	at org.jkiss.dbeaver.ext.generic.model.GenericDataSource.openConnection(GenericDataSource.java:158)
	at org.jkiss.dbeaver.model.impl.jdbc.JDBCExecutionContext.connect(JDBCExecutionContext.java:124)
	at org.jkiss.dbeaver.model.impl.jdbc.JDBCRemoteInstance.initializeMainContext(JDBCRemoteInstance.java:106)
	at org.jkiss.dbeaver.model.impl.jdbc.JDBCRemoteInstance.<init>(JDBCRemoteInstance.java:61)
	at org.jkiss.dbeaver.model.impl.jdbc.JDBCDataSource.initializeRemoteInstance(JDBCDataSource.java:125)
	at org.jkiss.dbeaver.ext.generic.model.GenericDataSource.<init>(GenericDataSource.java:124)
	at org.jkiss.dbeaver.ext.sqlite.model.SQLiteDataSource.<init>(SQLiteDataSource.java:49)
	at org.jkiss.dbeaver.ext.sqlite.model.SQLiteMetaModel.createDataSourceImpl(SQLiteMetaModel.java:223)
	at org.jkiss.dbeaver.ext.generic.GenericDataSourceProvider.openDataSource(GenericDataSourceProvider.java:57)
	at org.jkiss.dbeaver.registry.DataSourceDescriptor.openDataSource(DataSourceDescriptor.java:1413)
	at org.jkiss.dbeaver.registry.DataSourceDescriptor.connect0(DataSourceDescriptor.java:1271)
	at org.jkiss.dbeaver.registry.DataSourceDescriptor.connect(DataSourceDescriptor.java:1061)
	at org.jkiss.dbeaver.runtime.jobs.ConnectJob.run(ConnectJob.java:78)
	at org.jkiss.dbeaver.runtime.jobs.ConnectionTestJob.run(ConnectionTestJob.java:102)
	at io.cloudbeaver.service.ConnectionControllerCE.testConnection(ConnectionControllerCE.java:335)
	at io.cloudbeaver.service.core.impl.WebServiceCore.testConnection(WebServiceCore.java:419)
	at java.base/jdk.internal.reflect.DirectMethodHandleAccessor.invoke(DirectMethodHandleAccessor.java:103)
	at java.base/java.lang.reflect.Method.invoke(Method.java:580)

The default works to test but get the first error of the issue:

Image
<!-- gh-comment-id:3312203932 --> @webysther commented on GitHub (Sep 19, 2025): > Hello, [@webysther](https://github.com/webysther) ! Thanks for the report🦫 > > Quick question to align expectations: do you know of any setup where a SQLite DB in WAL mode works from a directory mounted read-only with a read-only connection? Or is this a desired behavior you’d like us to support? Our understanding is that WAL requires write access to create/update the *.db-wal and *.db-shm files next to the database file. > > Could you share a minimal repro and environment details? > > * CloudBeaver version/build, deployment (Docker? image tag), OS/filesystem, mount options. > * SQLite version / JDBC driver version. > * Exact connection string (e.g., plain path vs file:/…?mode=ro / immutable=1). > * Whether my.db-wal / my.db-shm exist before connecting. > > Possible workarounds meanwhile: > > * If the folder must stay read-only: open with file:/path/my.db?mode=ro&immutable=1, or switch the DB to PRAGMA journal_mode=DELETE (no WAL). Both allow read-only browsing. > * If WAL is required: mount that directory read-write (or copy the DB to a writable location before connecting), since WAL/shm must live alongside the DB file. > > Thank you! 🦫 If the option need to be added like `?mode=ro&immutable=1` why not add this option in the path when open the connection when I mark as `read-only` in the options? BTW (don't work): <img width="1060" height="814" alt="Image" src="https://github.com/user-attachments/assets/006905b2-90ab-40e5-a5ae-97b6c08f32cf" /> ```log java.sql.SQLException: opening db: '/mnt/jellyfin/jellyfin.db?immutable=1&mode=ro': Permission denied at org.sqlite.SQLiteConnection.open(SQLiteConnection.java:271) at org.sqlite.SQLiteConnection.<init>(SQLiteConnection.java:67) at org.sqlite.jdbc3.JDBC3Connection.<init>(JDBC3Connection.java:28) at org.sqlite.jdbc4.JDBC4Connection.<init>(JDBC4Connection.java:19) at org.sqlite.JDBC.createConnection(JDBC.java:106) at org.sqlite.JDBC.connect(JDBC.java:79) at org.jkiss.dbeaver.model.impl.jdbc.JDBCConnectionOpener.run(JDBCConnectionOpener.java:112) at org.jkiss.dbeaver.model.impl.jdbc.JDBCConnectionOpener.run(JDBCConnectionOpener.java:86) at org.jkiss.dbeaver.model.impl.jdbc.JDBCDataSource.openConnection(JDBCDataSource.java:215) at org.jkiss.dbeaver.model.impl.jdbc.JDBCDataSource.openConnection(JDBCDataSource.java:133) at org.jkiss.dbeaver.ext.generic.model.GenericDataSource.openConnection(GenericDataSource.java:158) at org.jkiss.dbeaver.model.impl.jdbc.JDBCExecutionContext.connect(JDBCExecutionContext.java:124) at org.jkiss.dbeaver.model.impl.jdbc.JDBCRemoteInstance.initializeMainContext(JDBCRemoteInstance.java:106) at org.jkiss.dbeaver.model.impl.jdbc.JDBCRemoteInstance.<init>(JDBCRemoteInstance.java:61) at org.jkiss.dbeaver.model.impl.jdbc.JDBCDataSource.initializeRemoteInstance(JDBCDataSource.java:125) at org.jkiss.dbeaver.ext.generic.model.GenericDataSource.<init>(GenericDataSource.java:124) at org.jkiss.dbeaver.ext.sqlite.model.SQLiteDataSource.<init>(SQLiteDataSource.java:49) at org.jkiss.dbeaver.ext.sqlite.model.SQLiteMetaModel.createDataSourceImpl(SQLiteMetaModel.java:223) at org.jkiss.dbeaver.ext.generic.GenericDataSourceProvider.openDataSource(GenericDataSourceProvider.java:57) at org.jkiss.dbeaver.registry.DataSourceDescriptor.openDataSource(DataSourceDescriptor.java:1413) at org.jkiss.dbeaver.registry.DataSourceDescriptor.connect0(DataSourceDescriptor.java:1271) at org.jkiss.dbeaver.registry.DataSourceDescriptor.connect(DataSourceDescriptor.java:1061) at org.jkiss.dbeaver.runtime.jobs.ConnectJob.run(ConnectJob.java:78) at org.jkiss.dbeaver.runtime.jobs.ConnectionTestJob.run(ConnectionTestJob.java:102) at io.cloudbeaver.service.ConnectionControllerCE.testConnection(ConnectionControllerCE.java:335) at io.cloudbeaver.service.core.impl.WebServiceCore.testConnection(WebServiceCore.java:419) at java.base/jdk.internal.reflect.DirectMethodHandleAccessor.invoke(DirectMethodHandleAccessor.java:103) at java.base/java.lang.reflect.Method.invoke(Method.java:580) ``` The default works to test but get the first error of the issue: <img width="2366" height="1727" alt="Image" src="https://github.com/user-attachments/assets/7b975d7a-2684-40f7-bd59-c978dfc20207" />
Author
Owner

@webysther commented on GitHub (Sep 19, 2025):

Even with the internal user o cloudbeaver of 8978 and also this driver options:

jdbc.explicit_readonly=1
open_mode=1

Image Image Image

In additional step I have tested with journal OFF:

Image

Set but in path or in the driver properties in diferent mixed ways, don't work.

<!-- gh-comment-id:3312227982 --> @webysther commented on GitHub (Sep 19, 2025): Even with the internal user o cloudbeaver of `8978` and also this driver options: `jdbc.explicit_readonly=1` `open_mode=1` <img width="854" height="612" alt="Image" src="https://github.com/user-attachments/assets/f5b72d79-91b2-45f1-be8f-81aa3108bc06" /> <img width="1206" height="330" alt="Image" src="https://github.com/user-attachments/assets/dfa17cae-fb08-4be6-ada5-a0591e35ee50" /> <img width="913" height="270" alt="Image" src="https://github.com/user-attachments/assets/374a2160-9917-430d-88c7-1eaf95ad87d3" /> In additional step I have tested with journal OFF: <img width="1308" height="308" alt="Image" src="https://github.com/user-attachments/assets/071948e8-debe-46c3-bf9d-907607034f05" /> Set but in path or in the driver properties in diferent mixed ways, don't work.
Author
Owner

@dariamarutkina commented on GitHub (Sep 19, 2025):

Thanks for the detailed answer!
And if you change the parameter journal_mode=DELETE ?

<!-- gh-comment-id:3312315699 --> @dariamarutkina commented on GitHub (Sep 19, 2025): Thanks for the detailed answer! And if you change the parameter journal_mode=DELETE ?
Author
Owner

@webysther commented on GitHub (Sep 19, 2025):

Thanks for the detailed answer! And if you change the parameter journal_mode=DELETE ?

Image
<!-- gh-comment-id:3312391060 --> @webysther commented on GitHub (Sep 19, 2025): > Thanks for the detailed answer! And if you change the parameter journal_mode=DELETE ? <img width="1083" height="742" alt="Image" src="https://github.com/user-attachments/assets/4d50a89c-e6c1-4da9-b999-b07190089abd" />
Author
Owner

@dariamarutkina commented on GitHub (Sep 19, 2025):

Thanks for the answer! 🦫

The stack trace shows SQLiteConfig.apply(...), which means a PRAGMA from Driver properties is being executed at connect time. Any PRAGMA journal_mode=... (OFF/DELETE/WAL) requires write access to change the DB header / create/remove journal files. On a read-only mount this inevitably fails with SQLITE_READONLY_DIRECTORY.

To read on a RO mount, please:

  1. Remove all PRAGMA-like driver properties that change the DB (e.g. journal_mode, journal_size_limit, etc.).

  2. Use URL configuration and pass only read-only flags (Switch to the URL tab)

jdbc:sqlite:file:/mnt/jellyfin/jellyfin.db?mode=ro&immutable=1

plus open_mode=65 (READONLY|URI). Do not set journal_mode in properties.

  1. If you then get “Permission denied”, that’s OS/SELinux: ensure UID/GID 8978 (CloudBeaver user in container) can traverse/read the path, and use :Z on SELinux volumes. Quick check:

docker exec -u 8978:8978 <cb> sh -lc 'head -c 0 /mnt/jellyfin/jellyfin.db && echo OK'

With the above, WAL + RO mount works via immutable=1 and no writes are attempted.

<!-- gh-comment-id:3312487838 --> @dariamarutkina commented on GitHub (Sep 19, 2025): Thanks for the answer! 🦫 The stack trace shows `SQLiteConfig.apply(...)`, which means a PRAGMA from Driver properties is being executed at connect time. Any `PRAGMA journal_mode=...` (OFF/DELETE/WAL) requires write access to change the DB header / create/remove journal files. On a read-only mount this inevitably fails with `SQLITE_READONLY_DIRECTORY.` To read on a RO mount, please: 1. Remove all PRAGMA-like driver properties that change the DB (e.g. journal_mode, journal_size_limit, etc.). 2. Use URL configuration and pass only read-only flags (Switch to the URL tab) `jdbc:sqlite:file:/mnt/jellyfin/jellyfin.db?mode=ro&immutable=1` plus open_mode=65 (READONLY|URI). Do not set journal_mode in properties. 3. If you then get “Permission denied”, that’s OS/SELinux: ensure UID/GID 8978 (CloudBeaver user in container) can traverse/read the path, and use :Z on SELinux volumes. Quick check: `docker exec -u 8978:8978 <cb> sh -lc 'head -c 0 /mnt/jellyfin/jellyfin.db && echo OK'` With the above, WAL + RO mount works via immutable=1 and no writes are attempted.
Author
Owner

@webysther commented on GitHub (Sep 19, 2025):

Thanks for the answer! 🦫

The stack trace shows SQLiteConfig.apply(...), which means a PRAGMA from Driver properties is being executed at connect time. Any PRAGMA journal_mode=... (OFF/DELETE/WAL) requires write access to change the DB header / create/remove journal files. On a read-only mount this inevitably fails with SQLITE_READONLY_DIRECTORY.

To read on a RO mount, please:

  1. Remove all PRAGMA-like driver properties that change the DB (e.g. journal_mode, journal_size_limit, etc.).
  2. Use URL configuration and pass only read-only flags (Switch to the URL tab)

jdbc:sqlite:file:/mnt/jellyfin/jellyfin.db?mode=ro&immutable=1

plus open_mode=65 (READONLY|URI). Do not set journal_mode in properties.

  1. If you then get “Permission denied”, that’s OS/SELinux: ensure UID/GID 8978 (CloudBeaver user in container) can traverse/read the path, and use :Z on SELinux volumes. Quick check:

docker exec -u 8978:8978 <cb> sh -lc 'head -c 0 /mnt/jellyfin/jellyfin.db && echo OK'

With the above, WAL + RO mount works via immutable=1 and no writes are attempted.

No driver properties:

webs@docker-tech:/data/docker$ docker exec -u 8978:8978 app-sql sh -lc 'head -c 0 /mnt/jellyfin/jellyfin.db && echo OK'
OK

webs@docker-tech:/data/docker$ cat /etc/fstab 
...
sshfs#webs@e1-plsi07.lan:/data/docker/jellyfin/config/data/data /mnt/plsi07/jellyfin fuse ro,defaults,_netdev,users,IdentityFile=/home/webs/.ssh/id_ed25519,allow_other,uid=8978,gid=8978 0 0
Image Image

Even switching open_mode to be inside driver properties don't work either. I few months ago worked without problem, I think its some kind regression, I use only few hours every some months of without usage.

<!-- gh-comment-id:3313621736 --> @webysther commented on GitHub (Sep 19, 2025): > Thanks for the answer! 🦫 > > The stack trace shows `SQLiteConfig.apply(...)`, which means a PRAGMA from Driver properties is being executed at connect time. Any `PRAGMA journal_mode=...` (OFF/DELETE/WAL) requires write access to change the DB header / create/remove journal files. On a read-only mount this inevitably fails with `SQLITE_READONLY_DIRECTORY.` > > To read on a RO mount, please: > > 1. Remove all PRAGMA-like driver properties that change the DB (e.g. journal_mode, journal_size_limit, etc.). > 2. Use URL configuration and pass only read-only flags (Switch to the URL tab) > > `jdbc:sqlite:file:/mnt/jellyfin/jellyfin.db?mode=ro&immutable=1` > > plus open_mode=65 (READONLY|URI). Do not set journal_mode in properties. > > 3. If you then get “Permission denied”, that’s OS/SELinux: ensure UID/GID 8978 (CloudBeaver user in container) can traverse/read the path, and use :Z on SELinux volumes. Quick check: > > `docker exec -u 8978:8978 <cb> sh -lc 'head -c 0 /mnt/jellyfin/jellyfin.db && echo OK'` > > With the above, WAL + RO mount works via immutable=1 and no writes are attempted. No driver properties: ```sh webs@docker-tech:/data/docker$ docker exec -u 8978:8978 app-sql sh -lc 'head -c 0 /mnt/jellyfin/jellyfin.db && echo OK' OK webs@docker-tech:/data/docker$ cat /etc/fstab ... sshfs#webs@e1-plsi07.lan:/data/docker/jellyfin/config/data/data /mnt/plsi07/jellyfin fuse ro,defaults,_netdev,users,IdentityFile=/home/webs/.ssh/id_ed25519,allow_other,uid=8978,gid=8978 0 0 ``` <img width="2011" height="904" alt="Image" src="https://github.com/user-attachments/assets/662960d2-b8fd-44c5-a406-45dcd9c2a2cf" /> <img width="1888" height="1260" alt="Image" src="https://github.com/user-attachments/assets/2272b390-4da2-4af0-8b64-9d5acd61a7a0" /> Even switching `open_mode` to be inside driver properties don't work either. I few months ago worked without problem, I think its some kind regression, I use only few hours every some months of without usage.
Author
Owner

@dariamarutkina commented on GitHub (Sep 19, 2025):

Thank you very much for the detailed answer! 💙

Could you please try switching the configuration from Manual to URL and set the connection string to:

jdbc:sqlite:file:/mnt/jellyfin/jellyfin.db?mode=ro&immutable=1

In the driver properties, keep only:

open_mode = 65

<!-- gh-comment-id:3313725900 --> @dariamarutkina commented on GitHub (Sep 19, 2025): Thank you very much for the detailed answer! 💙 Could you please try switching the configuration from Manual to URL and set the connection string to: `jdbc:sqlite:file:/mnt/jellyfin/jellyfin.db?mode=ro&immutable=1` In the driver properties, keep only: `open_mode = 65`
Author
Owner

@webysther commented on GitHub (Sep 19, 2025):

Thank you very much for the detailed answer! 💙

Could you please try switching the configuration from Manual to URL and set the connection string to:

jdbc:sqlite:file:/mnt/jellyfin/jellyfin.db?mode=ro&immutable=1

In the driver properties, keep only:

open_mode = 65

I make the install of sqlite3 in the cli of server and the connection string works for the same file.

Image Image

PS: works out-of-box without need of any option, I think its a regression in the cloudbeaver.

But not in the cloudbeaver:

Image

I recommend to build a test and test in your end to track as a test.

<!-- gh-comment-id:3313739679 --> @webysther commented on GitHub (Sep 19, 2025): > Thank you very much for the detailed answer! 💙 > > Could you please try switching the configuration from Manual to URL and set the connection string to: > > `jdbc:sqlite:file:/mnt/jellyfin/jellyfin.db?mode=ro&immutable=1` > > In the driver properties, keep only: > > `open_mode = 65` I make the install of `sqlite3` in the cli of server and the connection string works for the same file. <img width="767" height="163" alt="Image" src="https://github.com/user-attachments/assets/50dc1734-729d-4af6-a417-9b78b0e84e75" /> <img width="927" height="481" alt="Image" src="https://github.com/user-attachments/assets/bdfafbb3-fc4d-4969-ac86-90d0475bb8bd" /> PS: works out-of-box without need of any option, I think its a regression in the cloudbeaver. But not in the cloudbeaver: <img width="2007" height="1349" alt="Image" src="https://github.com/user-attachments/assets/1df2dfcf-544c-4c9d-855b-a395ff6ba54b" /> I recommend to build a test and test in your end to track as a test.
Author
Owner

@Wroud commented on GitHub (Sep 23, 2025):

It seems like you're trying to place *.db, *.wal, and *.shm in a read-only directory. This will block the SQLite driver from opening a connection.

There 3 two options:

  1. Use the database without WAL enabled

  2. Pre-generate the WAL file
    If you want a completely read-only snapshot, you can checkpoint all transactions (PRAGMA wal_checkpoint(FULL)) and then distribute only the main *.db file without the WAL.

    That way, the database is fully consistent and can be opened in strict read-only environments (e.g., mounted read-only, no WAL file at all).

  3. Place the database and *.wal, and *.shm in a writable directory

<!-- gh-comment-id:3324421151 --> @Wroud commented on GitHub (Sep 23, 2025): It seems like you're trying to place `*.db`, `*.wal`, and `*.shm` in a read-only directory. This will block the SQLite driver from opening a connection. There 3 two options: 1. Use the database without WAL enabled 2. Pre-generate the WAL file If you want a completely read-only snapshot, you can checkpoint all transactions (PRAGMA wal_checkpoint(FULL)) and then distribute only the main *.db file without the WAL. That way, the database is fully consistent and can be opened in strict read-only environments (e.g., mounted read-only, no WAL file at all). 3. Place the database and `*.wal`, and `*.shm` in a writable directory
Author
Owner

@webysther commented on GitHub (Sep 23, 2025):

It seems like you're trying to place *.db, *.wal, and *.shm in a read-only directory. This will block the SQLite driver from opening a connection.

There 3 two options:

  1. Use the database without WAL enabled
  2. Pre-generate the WAL file
    If you want a completely read-only snapshot, you can checkpoint all transactions (PRAGMA wal_checkpoint(FULL)) and then distribute only the main *.db file without the WAL.
    That way, the database is fully consistent and can be opened in strict read-only environments (e.g., mounted read-only, no WAL file at all).
  3. Place the database and *.wal, and *.shm in a writable directory

No, this is a cloudbeaver problem, I was able to use like I want in another server using just sqlite3 cli.

  1. I will not change the behavior of a db to use a simple tool.
  2. No way, not even recommended by sqlite
  3. Read-only means: no writes at all.

Will be nice the team just put effort to fix the problem. Just test what I'm saying, this is a error.

Security: need to mount using :rw over :ro is a security risk by design, this by default can be considered a security incident.

<!-- gh-comment-id:3324671951 --> @webysther commented on GitHub (Sep 23, 2025): > It seems like you're trying to place `*.db`, `*.wal`, and `*.shm` in a read-only directory. This will block the SQLite driver from opening a connection. > > There 3 two options: > > 1. Use the database without WAL enabled > 2. Pre-generate the WAL file > If you want a completely read-only snapshot, you can checkpoint all transactions (PRAGMA wal_checkpoint(FULL)) and then distribute only the main *.db file without the WAL. > That way, the database is fully consistent and can be opened in strict read-only environments (e.g., mounted read-only, no WAL file at all). > 3. Place the database and `*.wal`, and `*.shm` in a writable directory No, this is a cloudbeaver problem, I was able to use like I want in another server using just sqlite3 cli. 1. I will not change the behavior of a db to use a simple tool. 2. No way, not even recommended by sqlite 3. Read-only means: no writes at all. Will be nice the team just put effort to fix the problem. Just test what I'm saying, this is a error. Security: need to mount using :rw over :ro is a security risk by design, this by default can be considered a security incident.
Author
Owner

@Wroud commented on GitHub (Sep 23, 2025):

 @webysther, sorry, I misunderstood how the WAL file works in read-only systems; indeed, it would be able to read the database if the WAL file already exists.

We will fix this issue in future releases

<!-- gh-comment-id:3324796949 --> @Wroud commented on GitHub (Sep 23, 2025):  @webysther, sorry, I misunderstood how the WAL file works in read-only systems; indeed, it would be able to read the database if the WAL file already exists. We will fix this issue in future releases
Author
Owner

@HocKu7 commented on GitHub (Nov 20, 2025):

@webysther Please update the JDBC URL to use SQLite URI form:
jdbc:sqlite:file:/mnt/jellyfin/jellyfin.db?mode=ro&immutable=1
and make sure the user running the CloudBeaver server has rx on /mnt and /mnt/jellyfin and r on jellyfin.db.
Please try again and let us know if the error persists.

<!-- gh-comment-id:3557656343 --> @HocKu7 commented on GitHub (Nov 20, 2025): @webysther Please update the JDBC URL to use SQLite URI form: `jdbc:sqlite:file:/mnt/jellyfin/jellyfin.db?mode=ro&immutable=1` and make sure the user running the CloudBeaver server has rx on /mnt and /mnt/jellyfin and r on jellyfin.db. Please try again and let us know if the error persists.
Author
Owner

@webysther commented on GitHub (Dec 13, 2025):

Hi, for sqlite I have switched to another better tool (https://docs.linuxserver.io/images/docker-sqlitebrowser) and I will not be able to test anymore, sorry.

<!-- gh-comment-id:3649947042 --> @webysther commented on GitHub (Dec 13, 2025): Hi, for sqlite I have switched to another better tool (https://docs.linuxserver.io/images/docker-sqlitebrowser) and I will not be able to test anymore, sorry.
Sign in to join this conversation.
No milestone
No project
No assignees
1 participant
Notifications
Due date
The due date is invalid or out of range. Please use the format "yyyy-mm-dd".

No due date set.

Dependencies

No dependencies set.

Reference
starred/cloudbeaver#1317
No description provided.