[GH-ISSUE #16157] issue: Backend cannot connect to Redis in cluster mode #56472

Closed
opened 2026-05-05 19:28:48 -05:00 by GiteaMirror · 15 comments
Owner

Originally created by @erhhung on GitHub (Jul 30, 2025).
Original GitHub issue: https://github.com/open-webui/open-webui/issues/16157

Check Existing Issues

  • I have searched the existing issues and discussions.
  • I am using the latest version of Open WebUI.

Installation Method

Other

Open WebUI Version

v0.6.18

Ollama Version (if applicable)

No response

Operating System

Docker image: Debian 12

Browser (if applicable)

No response

Confirmation

  • I have read and followed all instructions in README.md.
  • I am using the latest version of both Open WebUI and Ollama.
  • I have included the browser console logs.
  • I have included the Docker container logs.
  • I have provided every relevant configuration, setting, and environment variable used in my setup.
  • I have clearly listed every relevant configuration, custom setting, environment variable, and command-line option that influences my setup (such as Docker Compose overrides, .env values, browser settings, authentication configurations, etc).
  • I have documented step-by-step reproduction instructions that are precise, sequential, and leave nothing to interpretation. My steps:
  • Start with the initial platform/version/OS and dependencies used,
  • Specify exact install/launch/configure commands,
  • List URLs visited, user input (incl. example values/emails/passwords if needed),
  • Describe all options and toggles enabled or changed,
  • Include any files or environmental changes,
  • Identify the expected and actual result at each stage,
  • Ensure any reasonably skilled user can follow and hit the same issue.

Expected Behavior

Open WebUI backend currently supports connections to Redis in two modes only:

  1. Single non-HA instance, either using the default deployment (by Helm chart) or explicitly referenced by the REDIS_URL and WEBSOCKET_REDIS_URL environment variables.

    In this mode, the actual client classes used from the redis-py package is redis.Redis and redis.asyncio.client.Redis.

  2. HA mode using Sentinels, either deployed alongside Open WebUI by the redis-cluster subchart or explicitly referenced by the same REDIS_URL variables as above as well as REDIS_SENTINEL_HOSTS and WEBSOCKET_SENTINEL_HOSTS.

    In this mode, the actual client classes used (see /backend/open_webui/utils/redis.py) is redis.sentinel.Sentinel and redis.asyncio.sentinel.Sentinel.

It does NOT currently support the third mode, clustering (using sharding), whereby proper support on the client side is provided by the redis.cluster.RedisCluster and redis.asyncio.cluster.RedisCluster classes.

Without using the proper client classes when connecting to Redis deployed in cluster mode, websocket cannot successfully connect.

Actual Behavior

The server throws a redis.exceptions.MovedError exception.

Steps to Reproduce

  1. Configure Open WebUI server to connect to an existing Redis/Valkey cluster by setting the REDIS_URL and WEBSOCKET_REDIS_URL environment variables. The host specified in the URL can be any host in the cluster.
  2. When the server starts up, an exception may be thrown when attempting to read a value if the node specified in the URL does not happen to contain the hashed slot for that key.

Logs & Screenshots

ERROR [open_webui.main] Error updating models: 10575 192.168.0.223:6379
Traceback (most recent call last):
  File "<frozen runpy>", line 198, in _run_module_as_main
  File "<frozen runpy>", line 88, in _run_code
  File "/usr/local/lib/python3.11/site-packages/uvicorn/__main__.py", line 4, in <module>
    uvicorn.main()
  File "/usr/local/lib/python3.11/site-packages/click/core.py", line 1442, in __call__
    return self.main(*args, **kwargs)
           ^^^^^^^^^^^^^^^^^^^^^^^^^^
  File "/usr/local/lib/python3.11/site-packages/click/core.py", line 1363, in main
    rv = self.invoke(ctx)
         ^^^^^^^^^^^^^^^^
  File "/usr/local/lib/python3.11/site-packages/click/core.py", line 1226, in invoke
    return ctx.invoke(self.callback, **ctx.params)
           ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
  File "/usr/local/lib/python3.11/site-packages/click/core.py", line 794, in invoke
    return callback(*args, **kwargs)
           ^^^^^^^^^^^^^^^^^^^^^^^^^
  File "/usr/local/lib/python3.11/site-packages/uvicorn/main.py", line 413, in main
    run(
  File "/usr/local/lib/python3.11/site-packages/uvicorn/main.py", line 580, in run
    server.run()
  File "/usr/local/lib/python3.11/site-packages/uvicorn/server.py", line 67, in run
    return asyncio.run(self.serve(sockets=sockets))
           ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
  File "/usr/local/lib/python3.11/asyncio/runners.py", line 190, in run
    return runner.run(main)
           ^^^^^^^^^^^^^^^^
  File "/usr/local/lib/python3.11/asyncio/runners.py", line 118, in run
    return self._loop.run_until_complete(task)
           ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
  File "uvloop/loop.pyx", line 1518, in uvloop.loop.Loop.run_until_complete
  File "/usr/local/lib/python3.11/site-packages/uvicorn/server.py", line 71, in serve
    await self._serve(sockets)
  File "/usr/local/lib/python3.11/site-packages/uvicorn/server.py", line 78, in _serve
    config.load()
  File "/usr/local/lib/python3.11/site-packages/uvicorn/config.py", line 436, in load
    self.loaded_app = import_from_string(self.app)
                      ^^^^^^^^^^^^^^^^^^^^^^^^^^^^
  File "/usr/local/lib/python3.11/site-packages/uvicorn/importer.py", line 19, in import_from_string
    module = importlib.import_module(module_str)
             ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
  File "/usr/local/lib/python3.11/importlib/__init__.py", line 126, in import_module
    return _bootstrap._gcd_import(name[level:], package, level)
           ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
  File "<frozen importlib._bootstrap>", line 1204, in _gcd_import
  File "<frozen importlib._bootstrap>", line 1176, in _find_and_load
  File "<frozen importlib._bootstrap>", line 1147, in _find_and_load_unlocked
  File "<frozen importlib._bootstrap>", line 690, in _load_unlocked
  File "<frozen importlib._bootstrap_external>", line 940, in exec_module
  File "<frozen importlib._bootstrap>", line 241, in _call_with_frames_removed
  File "/app/backend/open_webui/main.py", line 909, in <module>
    app.state.config.RAG_EMBEDDING_ENGINE,
    ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
  File "/app/backend/open_webui/config.py", line 251, in __getattr__
    redis_value = self._redis.get(redis_key)
                  ^^^^^^^^^^^^^^^^^^^^^^^^^^
  File "/usr/local/lib/python3.11/site-packages/redis/commands/core.py", line 1829, in get
    return self.execute_command("GET", name, keys=[name])
           ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
  File "/usr/local/lib/python3.11/site-packages/redis/client.py", line 623, in execute_command
    return self._execute_command(*args, **options)
           ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
  File "/usr/local/lib/python3.11/site-packages/redis/client.py", line 634, in _execute_command
    return conn.retry.call_with_retry(
           ^^^^^^^^^^^^^^^^^^^^^^^^^^^
  File "/usr/local/lib/python3.11/site-packages/redis/retry.py", line 87, in call_with_retry
    return do()
           ^^^^
  File "/usr/local/lib/python3.11/site-packages/redis/client.py", line 635, in <lambda>
    lambda: self._send_command_parse_response(
            ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
  File "/usr/local/lib/python3.11/site-packages/redis/client.py", line 606, in _send_command_parse_response
    return self.parse_response(conn, command_name, **options)
           ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
  File "/usr/local/lib/python3.11/site-packages/redis/client.py", line 653, in parse_response
    response = connection.read_response()
               ^^^^^^^^^^^^^^^^^^^^^^^^^^
  File "/usr/local/lib/python3.11/site-packages/redis/connection.py", line 666, in read_response
    raise response
redis.exceptions.MovedError: 10575 192.168.0.223:6379

Additional Information

No response

Originally created by @erhhung on GitHub (Jul 30, 2025). Original GitHub issue: https://github.com/open-webui/open-webui/issues/16157 ### Check Existing Issues - [x] I have searched the existing issues and discussions. - [x] I am using the latest version of Open WebUI. ### Installation Method Other ### Open WebUI Version v0.6.18 ### Ollama Version (if applicable) _No response_ ### Operating System Docker image: Debian 12 ### Browser (if applicable) _No response_ ### Confirmation - [x] I have read and followed all instructions in `README.md`. - [x] I am using the latest version of **both** Open WebUI and Ollama. - [x] I have included the browser console logs. - [x] I have included the Docker container logs. - [x] I have **provided every relevant configuration, setting, and environment variable used in my setup.** - [x] I have clearly **listed every relevant configuration, custom setting, environment variable, and command-line option that influences my setup** (such as Docker Compose overrides, .env values, browser settings, authentication configurations, etc). - [x] I have documented **step-by-step reproduction instructions that are precise, sequential, and leave nothing to interpretation**. My steps: - Start with the initial platform/version/OS and dependencies used, - Specify exact install/launch/configure commands, - List URLs visited, user input (incl. example values/emails/passwords if needed), - Describe all options and toggles enabled or changed, - Include any files or environmental changes, - Identify the expected and actual result at each stage, - Ensure any reasonably skilled user can follow and hit the same issue. ### Expected Behavior Open WebUI backend currently supports connections to Redis in two modes only: 1. **Single** _non-HA_ instance, either using the default deployment (by [Helm chart](https://github.com/open-webui/helm-charts/tree/main/charts/open-webui)) or explicitly referenced by the [`REDIS_URL`](https://docs.openwebui.com/getting-started/env-configuration/#redis_url) and [`WEBSOCKET_REDIS_URL`](https://docs.openwebui.com/getting-started/env-configuration/#websocket_redis_url) environment variables. In this mode, the actual client classes used from the [`redis-py`](https://pypi.org/project/redis/) package is [`redis.Redis`](https://redis.readthedocs.io/en/stable/connections.html#generic-client) and [`redis.asyncio.client.Redis`](https://redis.readthedocs.io/en/stable/connections.html#async-client). 2. HA mode using **Sentinels**, either deployed alongside Open WebUI by the `redis-cluster` subchart or explicitly referenced by the same `REDIS_URL` variables as above as well as [`REDIS_SENTINEL_HOSTS`](https://docs.openwebui.com/getting-started/env-configuration/#redis_sentinel_hosts) and [`WEBSOCKET_SENTINEL_HOSTS`](https://docs.openwebui.com/getting-started/env-configuration/#websocket_sentinel_hosts). In this mode, the actual client classes used _(see [`/backend/open_webui/utils/redis.py`](https://github.com/open-webui/open-webui/blob/main/backend/open_webui/utils/redis.py#L108))_ is [`redis.sentinel.Sentinel`](https://redis.readthedocs.io/en/stable/connections.html#sentinel-client) and [`redis.asyncio.sentinel.Sentinel`](https://redis.readthedocs.io/en/stable/connections.html#sentinel-client). It does NOT currently support the third mode, **clustering** _(using sharding)_, whereby proper support on the client side is provided by the [`redis.cluster.RedisCluster`](https://redis.readthedocs.io/en/stable/connections.html#cluster-client) and [`redis.asyncio.cluster.RedisCluster`](https://redis.readthedocs.io/en/stable/connections.html#async-cluster-client) classes. Without using the proper client classes when connecting to Redis deployed in cluster mode, websocket cannot successfully connect. ### Actual Behavior The server throws a [`redis.exceptions.MovedError`](https://redis.readthedocs.io/en/stable/exceptions.html#redis.exceptions.MovedError) exception. ### Steps to Reproduce 1. Configure Open WebUI server to connect to an existing Redis/Valkey cluster by setting the `REDIS_URL` and `WEBSOCKET_REDIS_URL` environment variables. The host specified in the URL can be _any_ host in the cluster. 2. When the server starts up, an exception may be thrown when attempting to read a value if the node specified in the URL does not happen to contain the hashed slot for that key. ### Logs & Screenshots ``` ERROR [open_webui.main] Error updating models: 10575 192.168.0.223:6379 Traceback (most recent call last): File "<frozen runpy>", line 198, in _run_module_as_main File "<frozen runpy>", line 88, in _run_code File "/usr/local/lib/python3.11/site-packages/uvicorn/__main__.py", line 4, in <module> uvicorn.main() File "/usr/local/lib/python3.11/site-packages/click/core.py", line 1442, in __call__ return self.main(*args, **kwargs) ^^^^^^^^^^^^^^^^^^^^^^^^^^ File "/usr/local/lib/python3.11/site-packages/click/core.py", line 1363, in main rv = self.invoke(ctx) ^^^^^^^^^^^^^^^^ File "/usr/local/lib/python3.11/site-packages/click/core.py", line 1226, in invoke return ctx.invoke(self.callback, **ctx.params) ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ File "/usr/local/lib/python3.11/site-packages/click/core.py", line 794, in invoke return callback(*args, **kwargs) ^^^^^^^^^^^^^^^^^^^^^^^^^ File "/usr/local/lib/python3.11/site-packages/uvicorn/main.py", line 413, in main run( File "/usr/local/lib/python3.11/site-packages/uvicorn/main.py", line 580, in run server.run() File "/usr/local/lib/python3.11/site-packages/uvicorn/server.py", line 67, in run return asyncio.run(self.serve(sockets=sockets)) ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ File "/usr/local/lib/python3.11/asyncio/runners.py", line 190, in run return runner.run(main) ^^^^^^^^^^^^^^^^ File "/usr/local/lib/python3.11/asyncio/runners.py", line 118, in run return self._loop.run_until_complete(task) ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ File "uvloop/loop.pyx", line 1518, in uvloop.loop.Loop.run_until_complete File "/usr/local/lib/python3.11/site-packages/uvicorn/server.py", line 71, in serve await self._serve(sockets) File "/usr/local/lib/python3.11/site-packages/uvicorn/server.py", line 78, in _serve config.load() File "/usr/local/lib/python3.11/site-packages/uvicorn/config.py", line 436, in load self.loaded_app = import_from_string(self.app) ^^^^^^^^^^^^^^^^^^^^^^^^^^^^ File "/usr/local/lib/python3.11/site-packages/uvicorn/importer.py", line 19, in import_from_string module = importlib.import_module(module_str) ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ File "/usr/local/lib/python3.11/importlib/__init__.py", line 126, in import_module return _bootstrap._gcd_import(name[level:], package, level) ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ File "<frozen importlib._bootstrap>", line 1204, in _gcd_import File "<frozen importlib._bootstrap>", line 1176, in _find_and_load File "<frozen importlib._bootstrap>", line 1147, in _find_and_load_unlocked File "<frozen importlib._bootstrap>", line 690, in _load_unlocked File "<frozen importlib._bootstrap_external>", line 940, in exec_module File "<frozen importlib._bootstrap>", line 241, in _call_with_frames_removed File "/app/backend/open_webui/main.py", line 909, in <module> app.state.config.RAG_EMBEDDING_ENGINE, ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ File "/app/backend/open_webui/config.py", line 251, in __getattr__ redis_value = self._redis.get(redis_key) ^^^^^^^^^^^^^^^^^^^^^^^^^^ File "/usr/local/lib/python3.11/site-packages/redis/commands/core.py", line 1829, in get return self.execute_command("GET", name, keys=[name]) ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ File "/usr/local/lib/python3.11/site-packages/redis/client.py", line 623, in execute_command return self._execute_command(*args, **options) ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ File "/usr/local/lib/python3.11/site-packages/redis/client.py", line 634, in _execute_command return conn.retry.call_with_retry( ^^^^^^^^^^^^^^^^^^^^^^^^^^^ File "/usr/local/lib/python3.11/site-packages/redis/retry.py", line 87, in call_with_retry return do() ^^^^ File "/usr/local/lib/python3.11/site-packages/redis/client.py", line 635, in <lambda> lambda: self._send_command_parse_response( ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ File "/usr/local/lib/python3.11/site-packages/redis/client.py", line 606, in _send_command_parse_response return self.parse_response(conn, command_name, **options) ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ File "/usr/local/lib/python3.11/site-packages/redis/client.py", line 653, in parse_response response = connection.read_response() ^^^^^^^^^^^^^^^^^^^^^^^^^^ File "/usr/local/lib/python3.11/site-packages/redis/connection.py", line 666, in read_response raise response redis.exceptions.MovedError: 10575 192.168.0.223:6379 ``` ### Additional Information _No response_
GiteaMirror added the bug label 2026-05-05 19:28:48 -05:00
Author
Owner

@tjbck commented on GitHub (Aug 4, 2025):

Addressed

<!-- gh-comment-id:3150313584 --> @tjbck commented on GitHub (Aug 4, 2025): Addressed
Author
Owner

@sanchitbhavsar commented on GitHub (Aug 13, 2025):

@erhhung how should be the REDIS_KEY_PREFIX defined in the cluster mode. I am running on single node currently and I add kez variable for this {open-webui} but I believe in cluster we have key-value pair to be passed. Could you please let me know, thanks.

<!-- gh-comment-id:3182639949 --> @sanchitbhavsar commented on GitHub (Aug 13, 2025): @erhhung how should be the `REDIS_KEY_PREFIX` defined in the cluster mode. I am running on single node currently and I add kez variable for this `{open-webui}` but I believe in cluster we have key-value pair to be passed. Could you please let me know, thanks.
Author
Owner

@rgaricano commented on GitHub (Aug 13, 2025):

@erhhung how should be the REDIS_KEY_PREFIX defined in the cluster mode. I am running on single node currently and I add kez variable for this {open-webui} but I believe in cluster we have key-value pair to be passed. Could you please let me know, thanks.

https://github.com/open-webui/open-webui/discussions/15834

<!-- gh-comment-id:3182660742 --> @rgaricano commented on GitHub (Aug 13, 2025): > [@erhhung](https://github.com/erhhung) how should be the `REDIS_KEY_PREFIX` defined in the cluster mode. I am running on single node currently and I add kez variable for this `{open-webui}` but I believe in cluster we have key-value pair to be passed. Could you please let me know, thanks. https://github.com/open-webui/open-webui/discussions/15834
Author
Owner

@sanchitbhavsar commented on GitHub (Aug 13, 2025):

@rgaricano so this should work {open-webui}:config:* correct?

<!-- gh-comment-id:3182691512 --> @sanchitbhavsar commented on GitHub (Aug 13, 2025): @rgaricano so this should work `{open-webui}:config:*` correct?
Author
Owner

@rgaricano commented on GitHub (Aug 13, 2025):

I think so, but I don't know so much about redis clustering.

I think that when clustering the difference is in the redis-url, and then it's needed that redis request is in "cluster mode" to discover the host. That funcionality was added recently.

Sure that Erhhung can respond, but ask it in the refered thread too, there are people that have differents redis deployments with deep knowledge about.

<!-- gh-comment-id:3182732538 --> @rgaricano commented on GitHub (Aug 13, 2025): I think so, but I don't know so much about redis clustering. I think that when clustering the difference is in the redis-url, and then it's needed that redis request is in "cluster mode" to discover the host. That funcionality was added recently. Sure that Erhhung can respond, but ask it in the refered thread too, there are people that have differents redis deployments with deep knowledge about.
Author
Owner

@erhhung commented on GitHub (Aug 19, 2025):

@sanchitbhavsar If you have a Redis HA setup with more than one host, OR sharing Redis between multiple Open WebUI instances, you shouldn't set REDIS_KEY_PREFIX to the same {open-webui} value, i.e., use Redis's curly braces hash tag feature, as that would always use "open-webui" to hash to the same one slot—you'd use different prefixes for each Open WebUI instance so that they act as namespaces, and let the key hashing mechanism distribute storage across all nodes—the reason why you even have a cluster.

EDIT: I'm not sure if Open WebUI is using multi-key operations like MGET, MSET, EVAL, MULTI/EXEC, which would require that all keys to hash to the same slot. If it is, then the safe bet would be to use prefixes like {open-webui-1} and {open-webui-2} for your instances.

In cluster mode, you point REDIS_URL to just one of the hosts in the cluster, known as the seed host. The Redis client will then issue the CLUSTER SLOTS command on initial connection to discover additional hosts (primaries and replicas) and the slot ranges assigned to each host. The Redis client will then know which host to directly talk to to get a value based on the hash slot it computed. If the seed host becomes unavailable but you still have replicas, then the client will retry requests on a replica if necessary.

<!-- gh-comment-id:3202308175 --> @erhhung commented on GitHub (Aug 19, 2025): @sanchitbhavsar If you have a Redis HA setup with more than one host, OR sharing Redis between multiple Open WebUI instances, you shouldn't set `REDIS_KEY_PREFIX` to the same `{open-webui}` value, _i.e., use Redis's curly braces hash tag feature_, as that would always use "`open-webui`" to hash to the same one slot—you'd use **different prefixes** for each Open WebUI instance so that they act as namespaces, and let the key hashing mechanism distribute storage across all nodes—the reason why you even have a cluster. EDIT: I'm not sure if Open WebUI is using multi-key operations like `MGET`, `MSET`, `EVAL`, `MULTI/EXEC`, which would require that **all keys to hash to the same slot**. If it is, then the safe bet would be to use prefixes like `{open-webui-1}` and `{open-webui-2}` for your instances. In cluster mode, you point `REDIS_URL` to just one of the hosts in the cluster, known as the **seed** host. The Redis client will then issue the `CLUSTER SLOTS` command on initial connection to discover additional hosts (primaries and replicas) and the slot ranges assigned to each host. The Redis client will then know which host to directly talk to to get a value based on the hash slot it computed. If the seed host becomes unavailable but you still have replicas, then the client will retry requests on a replica if necessary.
Author
Owner

@sanchitbhavsar commented on GitHub (Aug 21, 2025):

@sanchitbhavsar If you have a Redis HA setup with more than one host, OR sharing Redis between multiple Open WebUI instances, you shouldn't set REDIS_KEY_PREFIX to the same {open-webui} value, i.e., use Redis's curly braces hash tag feature, as that would always use "open-webui" to hash to the same one slot—you'd use different prefixes for each Open WebUI instance so that they act as namespaces, and let the key hashing mechanism distribute storage across all nodes—the reason why you even have a cluster.

EDIT: I'm not sure if Open WebUI is using multi-key operations like MGET, MSET, EVAL, MULTI/EXEC, which would require that all keys to hash to the same slot. If it is, then the safe bet would be to use prefixes like {open-webui-1} and {open-webui-2} for your instances.

In cluster mode, you point REDIS_URL to just one of the hosts in the cluster, known as the seed host. The Redis client will then issue the CLUSTER SLOTS command on initial connection to discover additional hosts (primaries and replicas) and the slot ranges assigned to each host. The Redis client will then know which host to directly talk to to get a value based on the hash slot it computed. If the seed host becomes unavailable but you still have replicas, then the client will retry requests on a replica if necessary.

@erhhung I am having issues with cluster mode, check: https://github.com/open-webui/open-webui/discussions/15834#discussioncomment-14175756

looking at the implementation on how keys are handle in openwebui,
438e5d966f/backend/open_webui/socket/utils.py (L182-L185)
438e5d966f/backend/open_webui/socket/main.py (L134-L137)

Should pass this key as prefix would work? REDIS_KEY_PREFIX="{open-webui}:" with semicolon but without *

<!-- gh-comment-id:3209924598 --> @sanchitbhavsar commented on GitHub (Aug 21, 2025): > [@sanchitbhavsar](https://github.com/sanchitbhavsar) If you have a Redis HA setup with more than one host, OR sharing Redis between multiple Open WebUI instances, you shouldn't set `REDIS_KEY_PREFIX` to the same `{open-webui}` value, _i.e., use Redis's curly braces hash tag feature_, as that would always use "`open-webui`" to hash to the same one slot—you'd use **different prefixes** for each Open WebUI instance so that they act as namespaces, and let the key hashing mechanism distribute storage across all nodes—the reason why you even have a cluster. > > EDIT: I'm not sure if Open WebUI is using multi-key operations like `MGET`, `MSET`, `EVAL`, `MULTI/EXEC`, which would require that **all keys to hash to the same slot**. If it is, then the safe bet would be to use prefixes like `{open-webui-1}` and `{open-webui-2}` for your instances. > > In cluster mode, you point `REDIS_URL` to just one of the hosts in the cluster, known as the **seed** host. The Redis client will then issue the `CLUSTER SLOTS` command on initial connection to discover additional hosts (primaries and replicas) and the slot ranges assigned to each host. The Redis client will then know which host to directly talk to to get a value based on the hash slot it computed. If the seed host becomes unavailable but you still have replicas, then the client will retry requests on a replica if necessary. @erhhung I am having issues with cluster mode, check: https://github.com/open-webui/open-webui/discussions/15834#discussioncomment-14175756 looking at the implementation on how keys are handle in openwebui, https://github.com/open-webui/open-webui/blob/438e5d966f0f64f9ea3feab22724a5bd96a4127b/backend/open_webui/socket/utils.py#L182-L185 https://github.com/open-webui/open-webui/blob/438e5d966f0f64f9ea3feab22724a5bd96a4127b/backend/open_webui/socket/main.py#L134-L137 Should pass this key as prefix would work? `REDIS_KEY_PREFIX="{open-webui}:"` with semicolon but without `*`
Author
Owner

@rgaricano commented on GitHub (Aug 22, 2025):

https://github.com/open-webui/open-webui/discussions/15834#discussioncomment-14179446

REDIS_KEY_PREFIX value should be just {open-webui} - you're overriding the default value, which is just open-webui and you've accidentally added a bunch of extra.

not value: "{open-webui}:config:*" or you'll end up with the f string expressing that to {open-webui}:config:*:config:actualparamkey

<!-- gh-comment-id:3214004070 --> @rgaricano commented on GitHub (Aug 22, 2025): https://github.com/open-webui/open-webui/discussions/15834#discussioncomment-14179446 > REDIS_KEY_PREFIX value should be just `{open-webui}` - you're overriding the default value, which is just `open-webui` and you've accidentally added a bunch of extra. > > not value: "{open-webui}:config:*" or you'll end up with the f string expressing that to `{open-webui}:config:*:config:actualparamkey`
Author
Owner

@AlbertDoesProgramming commented on GitHub (Aug 27, 2025):

So just to add on to this discussion. I'm wondering why in open_webui/socket/main.py, the RedisLock doesn't also use the REDIS_KEY_PREFIX?

I'm using ACLs to manage my redis security framework, and I want to gate OWUI access to redis behind access to keys with a certain shape, for example: ~open-webui-1:*. But the prefix isn't added to the name of the the RedisLock, and so when the lock fires, it throws because the key this creates would be out of scope.

Here's the code in question:

    clean_up_lock = RedisLock(
        redis_url=WEBSOCKET_REDIS_URL,
        lock_name="usage_cleanup_lock",
        timeout_secs=WEBSOCKET_REDIS_LOCK_TIMEOUT,
        redis_sentinels=redis_sentinels,
        redis_cluster=WEBSOCKET_REDIS_CLUSTER,
    )

Is there a good reason not to include the prefix against the lock name? I have a workaround right now I think, but I was under the impression that the prefix really would end up everywhere.

<!-- gh-comment-id:3228926258 --> @AlbertDoesProgramming commented on GitHub (Aug 27, 2025): So just to add on to this discussion. I'm wondering why in [`open_webui/socket/main.py`](https://github.com/open-webui/open-webui/blob/1db8dec4f52fc0fa8f8f7bfbb8ea5bde41fee17d/backend/open_webui/socket/main.py#L118), the RedisLock doesn't also use the REDIS_KEY_PREFIX? I'm using ACLs to manage my redis security framework, and I want to gate OWUI access to redis behind access to keys with a certain shape, for example: ~open-webui-1:*. But the prefix isn't added to the name of the the RedisLock, and so when the lock fires, it throws because the key this creates would be out of scope. Here's the code in question: ```python clean_up_lock = RedisLock( redis_url=WEBSOCKET_REDIS_URL, lock_name="usage_cleanup_lock", timeout_secs=WEBSOCKET_REDIS_LOCK_TIMEOUT, redis_sentinels=redis_sentinels, redis_cluster=WEBSOCKET_REDIS_CLUSTER, ) ``` Is there a good reason not to include the prefix against the lock name? I have a workaround right now I think, but I was under the impression that the prefix really would end up everywhere.
Author
Owner

@rgaricano commented on GitHub (Aug 27, 2025):

Yes, without change RedisLock Class, is a solution,
Replace lock_name=f"{REDIS_KEY_PREFIX}:usage_cleanup_lock",
in
df2428b356/backend/open_webui/socket/main.py (L118)

I search about and seem that it's the only place where the prefix could be necessary, all others seem that are properly managed.

<!-- gh-comment-id:3229005199 --> @rgaricano commented on GitHub (Aug 27, 2025): Yes, without change RedisLock Class, is a solution, Replace `lock_name=f"{REDIS_KEY_PREFIX}:usage_cleanup_lock", ` in https://github.com/open-webui/open-webui/blob/df2428b3569a34eb49792d384658118996de432d/backend/open_webui/socket/main.py#L118 I search about and seem that it's the only place where the prefix could be necessary, all others seem that are properly managed.
Author
Owner

@AlbertDoesProgramming commented on GitHub (Aug 27, 2025):

Yeah it seems to me a natural change to make. That said, I am curious about why it wasn't addressed in the previous change to add the prefix - this makes me think there's some sort of important reason for not doing it that I can't imagine haha!

<!-- gh-comment-id:3229620309 --> @AlbertDoesProgramming commented on GitHub (Aug 27, 2025): Yeah it seems to me a natural change to make. That said, I am curious about why it wasn't addressed in the previous change to add the prefix - this makes me think there's some sort of important reason for _not_ doing it that I can't imagine haha!
Author
Owner

@AlbertDoesProgramming commented on GitHub (Aug 27, 2025):

issue raised for this

<!-- gh-comment-id:3229837559 --> @AlbertDoesProgramming commented on GitHub (Aug 27, 2025): issue raised for this
Author
Owner

@rgaricano commented on GitHub (Aug 27, 2025):

& solved & merged

<!-- gh-comment-id:3230111526 --> @rgaricano commented on GitHub (Aug 27, 2025): & solved & merged
Author
Owner

@AlbertDoesProgramming commented on GitHub (Aug 28, 2025):

Thank you! ❤️

<!-- gh-comment-id:3232658969 --> @AlbertDoesProgramming commented on GitHub (Aug 28, 2025): Thank you! ❤️
Author
Owner

@AlbertDoesProgramming commented on GitHub (Aug 29, 2025):

Fwiw I've spotted another area where I think the same issue occurs but for tools.py and raised that here: issue-17032

<!-- gh-comment-id:3236572824 --> @AlbertDoesProgramming commented on GitHub (Aug 29, 2025): Fwiw I've spotted another area where I think the same issue occurs but for tools.py and raised that here: [issue-17032](https://github.com/open-webui/open-webui/issues/17032)
Sign in to join this conversation.
1 Participants
Notifications
Due Date
No due date set.
Dependencies

No dependencies set.

Reference: github-starred/open-webui#56472