mirror of
https://github.com/open-webui/open-webui.git
synced 2026-05-07 03:18:23 -05:00
[GH-ISSUE #17329] issue: SQLCipher Database with OpenWebUI on SQLite -> Closed Database Error #18243
Reference in New Issue
Block a user
Delete Branch "%!s()"
Deleting a branch is permanent. Although the deleted branch may continue to exist for a short time before it actually gets removed, it CANNOT be undone in most cases. Continue?
Originally created by @nboehlke on GitHub (Sep 10, 2025).
Original GitHub issue: https://github.com/open-webui/open-webui/issues/17329
Check Existing Issues
Installation Method
Docker
Open WebUI Version
v0.6.27
Ollama Version (if applicable)
v0.11.10
Operating System
RHEL 9.5
Browser (if applicable)
No response
Confirmation
README.md.Expected Behavior
Hi y'all,
Hi @rndmcnlly,
we are piloting OpenWebUI as an alternative to ChatGPT, etc and were delighted that even in the pilot stage we are able to implement DB encryption. As we use SQLite as DB in this stage (if scale, we may use PostGreSQL), we currently failing on using the new added feature "SQLCipher support for database encryption" #16132 and #16112
Actual Behavior
Based on the given feature, the additional layer SQLCipher should act as an intermediary between the OWUI app and the SQLite database. If everything works as expected, there should be no difference between the unencrypted and encrypted SQLite databases.
Steps to Reproduce
We already tried to build a Custom Image to integrate the mentioned sqlcipher3-wheels package by using:
command
podman build -t open-webui-sqlcipherfrom the Dockerfile
`# Use Open WebUI CUDA image as base
FROM ghcr.io/open-webui/open-webui:v0.6.27-cuda
Install the sqlcipher3-wheels package
RUN pip install sqlcipher3-wheels`
as a result we run the image via this run command:
podman run -d
-p 3000:8080
--network podman-intern
--device nvidia.com/gpu=all
-v open-webui_data:/app/backend/data
-e DATABASE_TYPE=sqlite+sqlcipher
-e DATABASE_PASSWORD=abc123
-e DATABASE_ENABLE_SQLITE_WAL=TRUE
-e DATABASE_DEDUPLICATE_INTERVAL=6.9
-e OLLAMA_BASE_URL=http://ollama:11434
-e ENABLE_MESSAGE_RATING=TRUE
-e ENABLE_ADMIN_CHAT_ACCESS=FALSE
-e ENABLE_ADMIN_WORKSPACE_CONTENT_ACCESS=FALSE
-e ENABLE_ADMIN_EXPORT=FALSE
-e PDF_EXTRACT_IMAGES=TRUE
-e VECTOR_DB=elasticsearch
-e ELASTICSEARCH_URL=http://elasticsearch:9200
--name open-webui
open-webui-sqlcipher
Result: OpenWebUI starts as expected, you can register as administrator from the beginning but ending up on the main chat page, no chats are loading + when switching to the admin page, the pod crashes (see logs).
Logs & Screenshots
The logs show that there has to be a problem with the sqlcipher implementation:
`podman logs open-webui
Loading WEBUI_SECRET_KEY from file, not provided as an environment variable.
Generating WEBUI_SECRET_KEY
Loading WEBUI_SECRET_KEY from .webui_secret_key
CUDA is enabled, appending LD_LIBRARY_PATH to include torch/cudnn & cublas libraries.
INFO [alembic.runtime.migration] Context impl SQLiteImpl.
INFO [alembic.runtime.migration] Will assume non-transactional DDL.
INFO [alembic.runtime.migration] Running upgrade -> 7e5b5dc7342b, init
INFO [alembic.runtime.migration] Running upgrade 7e5b5dc7342b -> ca81bd47c050, Add config table
INFO [alembic.runtime.migration] Running upgrade ca81bd47c050 -> c0fbf31ca0db, Update file table
INFO [alembic.runtime.migration] Running upgrade c0fbf31ca0db -> 6a39f3d8e55c, Add knowledge table
INFO [alembic.runtime.migration] Running upgrade 6a39f3d8e55c -> 242a2047eae0, Update chat table
INFO [alembic.runtime.migration] Running upgrade 242a2047eae0 -> 1af9b942657b, Migrate tags
INFO [alembic.runtime.migration] Running upgrade 1af9b942657b -> 3ab32c4b8f59, Update tags
INFO [alembic.runtime.migration] Running upgrade 3ab32c4b8f59 -> c69f45358db4, Add folder table
INFO [alembic.runtime.migration] Running upgrade c69f45358db4 -> c29facfe716b, Update file table path
INFO [alembic.runtime.migration] Running upgrade c29facfe716b -> af906e964978, Add feedback table
INFO [alembic.runtime.migration] Running upgrade af906e964978 -> 4ace53fd72c8, Update folder table and change DateTime to BigInteger for timestamp fields
INFO [alembic.runtime.migration] Running upgrade 4ace53fd72c8 -> 922e7a387820, Add group table
INFO [alembic.runtime.migration] Running upgrade 922e7a387820 -> 57c599a3cb57, Add channel table
INFO [alembic.runtime.migration] Running upgrade 57c599a3cb57 -> 7826ab40b532, Update file table
INFO [alembic.runtime.migration] Running upgrade 7826ab40b532 -> 3781e22d8b01, Update message & channel tables
INFO [alembic.runtime.migration] Running upgrade 3781e22d8b01 -> 9f0c9cd09105, Add note table
INFO [alembic.runtime.migration] Running upgrade 9f0c9cd09105 -> d31026856c01, Update folder table data
INFO [alembic.runtime.migration] Running upgrade d31026856c01 -> 018012973d35, Add indexes
INFO [alembic.runtime.migration] Running upgrade 018012973d35 -> 3af16a1c9fb6, update user table
INFO [alembic.runtime.migration] Running upgrade 3af16a1c9fb6 -> 38d63c18f30f, Add oauth_session table
WARNI [open_webui.env]
WARNING: CORS_ALLOW_ORIGIN IS SET TO '*' - NOT RECOMMENDED FOR PRODUCTION DEPLOYMENTS.
INFO [open_webui.env] VECTOR_DB: elasticsearch
INFO [open_webui.env] Embedding model set: sentence-transformers/all-MiniLM-L6-v2
WARNI [langchain_community.utils.user_agent] USER_AGENT environment variable not set, consider setting it to identify your requests.
Creating knowledge table
Migrating data from document table to knowledge table
Converting 'chat' column to JSON
Renaming 'chat' column to 'old_chat'
Adding new 'chat' column of type JSON
Dropping 'old_chat' column
Primary Key: {'name': None, 'constrained_columns': []}
Unique Constraints: [{'name': 'uq_id_user_id', 'column_names': ['id', 'user_id']}]
Indexes: [{'name': 'tag_id', 'column_names': ['id'], 'unique': 1, 'dialect_options': {}}]
Creating new primary key with 'id' and 'user_id'.
Dropping unique constraint: uq_id_user_id
Dropping unique index: tag_id
██████╗ ██████╗ ███████╗███╗ ██╗ ██╗ ██╗███████╗██████╗ ██╗ ██╗██╗
██╔═══██╗██╔══██╗██╔════╝████╗ ██║ ██║ ██║██╔══���═╝██╔══██╗██║ ██║██║
██║ ██║██████╔╝█████╗ ██╔██╗ ██║ ██║ █╗ ██║█████╗ ██████╔╝██║ ██║██║
██║ ██║██╔═══╝ ██╔══╝ ██║╚██╗██║ ██║███╗██║██╔══╝ ██╔══██╗██║ ██║██║
╚██████╔╝██║ ███████╗██║ ╚████║ ╚███╔███╔╝███████╗██████╔╝╚██████╔╝██║
╚═════╝ ╚═╝ ╚══════╝╚═╝ ╚═══╝ ╚══╝╚══╝ ╚══════╝╚═════╝ ╚═════╝ ╚═╝
v0.6.27 - building the best AI user interface.
https://github.com/open-webui/open-webui
Fetching 30 files: 100%|██████████| 30/30 [00:10<00:00, 2.90it/s]
INFO: Started server process [1]
INFO: Waiting for application startup.
2025-09-10 10:03:28.882 | INFO | open_webui.utils.logger:start_logger:162 - GLOBAL_LOG_LEVEL: INFO
2025-09-10 10:03:28.882 | INFO | open_webui.main:lifespan:541 - Installing external dependencies of functions and tools...
2025-09-10 10:03:28.887 | INFO | open_webui.utils.plugin:install_frontmatter_requirements:241 - No requirements found in frontmatter.
2025-09-10 10:03:31.033 | INFO | uvicorn.protocols.http.httptools_impl:send:476 - 172.16.13.203:0 - "GET / HTTP/1.0" 200
2025-09-10 10:03:31.051 | INFO | uvicorn.protocols.http.httptools_impl:send:476 - 172.16.13.203:0 - "GET /static/loader.js HTTP/1.0" 200
2025-09-10 10:03:31.051 | INFO | uvicorn.protocols.http.httptools_impl:send:476 - 172.16.13.203:0 - "GET /static/custom.css HTTP/1.0" 200
2025-09-10 10:03:31.057 | INFO | uvicorn.protocols.http.httptools_impl:send:476 - 172.16.13.203:0 - "GET /static/splash.png HTTP/1.0" 200
2025-09-10 10:03:31.373 | INFO | uvicorn.protocols.http.httptools_impl:send:476 - 172.16.13.203:0 - "GET /static/favicon.ico HTTP/1.0" 200
2025-09-10 10:03:31.386 | INFO | uvicorn.protocols.http.httptools_impl:send:476 - 172.16.13.203:0 - "GET /manifest.json HTTP/1.0" 200
2025-09-10 10:03:31.406 | INFO | uvicorn.protocols.http.httptools_impl:send:476 - 172.16.13.203:0 - "GET /static/logo.png HTTP/1.0" 200
2025-09-10 10:03:31.523 | INFO | uvicorn.protocols.http.httptools_impl:send:476 - 172.16.13.203:0 - "GET /api/config HTTP/1.0" 200
2025-09-10 10:03:31.528 | INFO | uvicorn.protocols.http.httptools_impl:send:476 - 172.16.13.203:0 - "GET /static/favicon.png HTTP/1.0" 200
2025-09-10 10:03:31.534 | INFO | uvicorn.protocols.http.httptools_impl:send:476 - 172.16.13.203:0 - "GET /api/v1/auths/ HTTP/1.0" 401
2025-09-10 10:03:45.231 | INFO | open_webui.models.auths:insert_new_auth:103 - insert_new_auth
2025-09-10 10:03:45.245 | INFO | open_webui.config:save:212 - Saving 'ENABLE_SIGNUP' to the database
2025-09-10 10:03:45.250 | INFO | uvicorn.protocols.http.httptools_impl:send:476 - 172.16.13.203:0 - "POST /api/v1/auths/signup HTTP/1.0" 200
2025-09-10 10:03:45.259 | INFO | uvicorn.protocols.http.httptools_impl:send:476 - 172.16.13.203:0 - "GET /api/config HTTP/1.0" 200
2025-09-10 10:03:45.281 | INFO | uvicorn.protocols.http.httptools_impl:send:476 - 172.16.13.203:0 - "GET /api/changelog HTTP/1.0" 200
2025-09-10 10:03:45.294 | INFO | uvicorn.protocols.http.httptools_impl:send:476 - 172.16.13.203:0 - "GET /static/favicon.png HTTP/1.0" 304
2025-09-10 10:03:45.304 | INFO | uvicorn.protocols.http.httptools_impl:send:476 - 172.16.13.203:0 - "GET /static/favicon.png HTTP/1.0" 304
2025-09-10 10:03:45.353 | INFO | uvicorn.protocols.http.httptools_impl:send:476 - 172.16.13.203:0 - "GET /api/v1/chats/archived?page=1&order_by=updated_at&direction=desc HTTP/1.0" 200
2025-09-10 10:03:45.363 | ERROR | sqlalchemy.engine.base:_safe_close_cursor:2215 - Error closing cursor
Traceback (most recent call last):
File "/usr/local/lib/python3.11/site-packages/sqlalchemy/engine/cursor.py", line 1136, in fetchall
rows = dbapi_cursor.fetchall()
│ └ <method 'fetchall' of 'sqlcipher3.dbapi2.Cursor' objects>
└ <sqlcipher3.dbapi2.Cursor object at 0x7efa90266250>
sqlcipher3.dbapi2.ProgrammingError: Cannot operate on a closed database.
During handling of the above exception, another exception occurred:
Traceback (most recent call last):
File "/usr/local/lib/python3.11/threading.py", line 1002, in _bootstrap
self._bootstrap_inner()
│ └ <function Thread._bootstrap_inner at 0x7efc526109a0>
└ <WorkerThread(AnyIO worker thread, started 139612668675776)>
File "/usr/local/lib/python3.11/threading.py", line 1045, in _bootstrap_inner
self.run()
│ └ <function WorkerThread.run at 0x7efa90385120>
└ <WorkerThread(AnyIO worker thread, started 139612668675776)>
File "/usr/local/lib/python3.11/site-packages/anyio/_backends/_asyncio.py", line 967, in run
result = context.run(func, *args)
│ │ │ └ ()
│ │ └ functools.partial(<function get_current_user at 0x7efb0824fb00>, auth_token=HTTPAuthorizationCredentials(scheme='Bearer', cre...
│ └ <method 'run' of '_contextvars.Context' objects>
└ <_contextvars.Context object at 0x7efa9023bd40>
File "/app/backend/open_webui/utils/auth.py", line 275, in get_current_user
user = Users.get_user_by_id(data["id"])
│ │ └ {'id': '6ff06fd6-be28-4880-9425-d506229c0399'}
│ └ <function UsersTable.get_user_by_id at 0x7efb083ad1c0>
└ <open_webui.models.users.UsersTable object at 0x7efb083ca890>
File "/app/backend/open_webui/models/users.py", line 179, in get_user_by_id
user = db.query(User).filter_by(id=id).first()
│ │ │ └ '6ff06fd6-be28-4880-9425-d506229c0399'
│ │ └ <class 'open_webui.models.users.User'>
│ └ <function Session.query at 0x7efb08bb2a20>
└ <sqlalchemy.orm.session.Session object at 0x7efa90228ed0>
File "/usr/local/lib/python3.11/site-packages/sqlalchemy/orm/query.py", line 2754, in first
return self.limit(1)._iter().first() # type: ignore
│ └ <function Query.limit at 0x7efb094ebec0>
└ <sqlalchemy.orm.query.Query object at 0x7efa90229390>
File "/usr/local/lib/python3.11/site-packages/sqlalchemy/engine/result.py", line 1784, in first
return self._only_one_row(
│ └ <function ResultInternal._only_one_row at 0x7efc4fdf3a60>
└ <sqlalchemy.engine.result.ScalarResult object at 0x7efa90216710>
File "/usr/local/lib/python3.11/site-packages/sqlalchemy/engine/result.py", line 749, in _only_one_row
row: Optional[_InterimRowType[Any]] = onerow(hard_close=True)
│ │ │ └ <bound method FilterResult._fetchone_impl of <sqlalchemy.engine.result.ScalarResult object at 0x7efa90216710>>
│ │ └ typing.Any
│ └ typing.Union[~_R, typing.Tuple[typing.Any, ...]]
└ typing.Optional
File "/usr/local/lib/python3.11/site-packages/sqlalchemy/engine/result.py", line 1671, in _fetchone_impl
return self._real_result._fetchone_impl(hard_close=hard_close)
│ │ └ True
│ └ <member '_real_result' of 'FilterResult' objects>
└ <sqlalchemy.engine.result.ScalarResult object at 0x7efa90216710>
File "/usr/local/lib/python3.11/site-packages/sqlalchemy/engine/result.py", line 2257, in _fetchone_impl
row = next(self.iterator, _NO_ROW)
│ │ └ <_NoRow._NO_ROW: 0>
│ └ <itertools.chain object at 0x7efa9026e6b0>
└ <sqlalchemy.engine.result.ChunkedIteratorResult object at 0x7efa901f2410>
File "/usr/local/lib/python3.11/site-packages/sqlalchemy/orm/loading.py", line 219, in chunks
fetch = cursor._raw_all_rows()
│ └ <function ResultInternal._raw_all_rows at 0x7efc4fdf3600>
└ <sqlalchemy.engine.cursor.CursorResult object at 0x7efa902656a0>
File "/usr/local/lib/python3.11/site-packages/sqlalchemy/engine/result.py", line 540, in _raw_all_rows
rows = self._fetchall_impl()
│ └ <function CursorResult._fetchall_impl at 0x7efc4fdd4040>
└ <sqlalchemy.engine.cursor.CursorResult object at 0x7efa902656a0>
File "/usr/local/lib/python3.11/site-packages/sqlalchemy/engine/cursor.py", line 2130, in _fetchall_impl
return self.cursor_strategy.fetchall(self, self.cursor)
│ │ │ │ └ <member 'cursor' of 'CursorResult' objects>
│ │ │ └ <sqlalchemy.engine.cursor.CursorResult object at 0x7efa902656a0>
│ │ └ <sqlalchemy.engine.cursor.CursorResult object at 0x7efa902656a0>
│ └ <member 'cursor_strategy' of 'CursorResult' objects>
└ <sqlalchemy.engine.cursor.CursorResult object at 0x7efa902656a0>
File "/usr/local/lib/python3.11/site-packages/sqlalchemy/engine/cursor.py", line 1140, in fetchall
self.handle_exception(result, dbapi_cursor, e)
│ │ │ │ └ ProgrammingError('Cannot operate on a closed database.')
│ │ │ └ <sqlcipher3.dbapi2.Cursor object at 0x7efa90266250>
│ │ └ <sqlalchemy.engine.cursor.CursorResult object at 0x7efa902656a0>
│ └ <function CursorFetchStrategy.handle_exception at 0x7efc4fdd9da0>
└ <sqlalchemy.engine.cursor.CursorFetchStrategy object at 0x7efc4fe870a0>
File "/usr/local/lib/python3.11/site-packages/sqlalchemy/engine/cursor.py", line 1081, in handle_exception
result.connection._handle_dbapi_exception(
│ └ <member 'connection' of 'CursorResult' objects>
└ <sqlalchemy.engine.cursor.CursorResult object at 0x7efa902656a0>
File "/usr/local/lib/python3.11/site-packages/sqlalchemy/engine/base.py", line 2337, in _handle_dbapi_exception
self._safe_close_cursor(cursor)
│ │ └ <sqlcipher3.dbapi2.Cursor object at 0x7efa90266250>
│ └ <function Connection._safe_close_cursor at 0x7efc4fe4ed40>
└ <sqlalchemy.engine.base.Connection object at 0x7efa90229750>
sqlcipher3.dbapi2.ProgrammingError: Cannot operate on a closed database.
2025-09-10 10:03:45.365 | INFO | uvicorn.protocols.http.httptools_impl:send:476 - 172.16.13.203:0 - "GET /api/v1/folders/ HTTP/1.0" 401
2025-09-10 10:03:45.368 | INFO | uvicorn.protocols.http.httptools_impl:send:476 - 172.16.13.203:0 - "GET /api/v1/channels/ HTTP/1.0" 200
2025-09-10 10:03:45.368 | INFO | uvicorn.protocols.http.httptools_impl:send:476 - 172.16.13.203:0 - "GET /api/v1/chats/?page=1 HTTP/1.0" 200
2025-09-10 10:03:45.450 | INFO | uvicorn.protocols.http.httptools_impl:send:476 - 172.16.13.203:0 - "GET /api/v1/users/user/settings HTTP/1.0" 200
2025-09-10 10:03:45.456 | INFO | open_webui.routers.openai:get_all_models:466 - get_all_models()
2025-09-10 10:03:45.456 | INFO | open_webui.routers.ollama:get_all_models:348 - get_all_models()`
Additional Information
No response