"CELERY_BROKER_URL parsing fails when redis password contains special characters like '#'" #15714

Closed
opened 2026-02-21 19:23:01 -05:00 by yindo · 0 comments
Owner

Originally created by @Sn0rt on GitHub (Jul 28, 2025).

Self Checks

  • I have read the Contributing Guide and Language Policy.
  • This is only for bug report, if you would like to ask a question, please head to Discussions.
  • I have searched for existing issues search for existing issues, including closed ones.
  • I confirm that I am using English to submit this report, otherwise it will be closed.
  • 【中文用户 & Non English User】请使用英语提交,否则会被关闭 :)
  • Please do not modify this template :) and fill in all the required fields.

Dify version

not applicable

Cloud or Self Hosted

Self Hosted (Docker)

Steps to reproduce

Celery uses kombu's parse_url method to parse URLs. This internal method supports parsing passwords containing special characters (requiring manual URL encoding).

However, the monitor task implemented in api/schedule/queue_monitor_task.py simply performs URL parsing. If the password contains a #, the parsing will fail.

In [1]: from urllib.parse import urlparse

In [2]: urlparse("redis://admin:complex%23pass%40word@127.0.0.1:6379/0")
Out[2]: ParseResult(scheme='redis', netloc='admin:complex%23pass%40word@127.0.0.1:6379', path='/0', params='', query='', fragment='')

In [3]: parsed =  urlparse("redis://admin:complex%23pass%40word@127.0.0.1:6379/0")

In [4]: parsed
Out[4]: ParseResult(scheme='redis', netloc='admin:complex%23pass%40word@127.0.0.1:6379', path='/0', params='', query='', fragment='')

In [5]: parsed.hostname
Out[5]: '127.0.0.1'

In [6]: parsed.password
Out[6]: 'complex%23pass%40word'

In [7]: parsed =  urlparse("redis://admin:complex#123@127.0.0.1:6379/0")

In [8]: parsed.password

In [9]:
## Current Code (Broken)
# In api/schedule/queue_monitor_task.py
parsed = urlparse(celery_broker_url)
host = parsed.hostname or "localhost"
port = parsed.port or 6379
password = parsed.password or None
redis_db = parsed.path.strip("/") or "1"

Impact

  • Users with Redis passwords containing special characters cannot connect
  • Silent connection failures that are hard to debug
  • Affects queue monitoring functionality

Proposed Solution

Have users URL-encode their passwords in advance if the password include special chart.

I have checked Celery and not found the same issue (this support url encoded url), so this seems to be the recommended solution.

Of course, another option is to use multiple environment variables to split the BROKER_URL used by Celery into pre-determined independent variables, such as CELERY_BROKER_USERNAME and CELERY_BROKER_PASSWORD.

    celery_app = Celery(
        app.name,
        task_cls=FlaskTask,
        broker=dify_config.CELERY_BROKER_URL,
        backend=dify_config.CELERY_BACKEND,
        task_ignore_result=True,
    )
>>> kombu.utils.url.parse_url("redis://admin:complex%23pass%40word@127.0.0.1:6379/0")
{'transport': 'redis', 'hostname': '127.0.0.1', 'port': 6379, 'userid': 'admin', 'password': 'complex#pass@word', 'virtual_host': '0'}

✔️ Expected Behavior

  The fix should handle all these scenarios correctly:
  - `redis://!asdfsfd#ABC/redis:6379/1` → password: `!asdfsfd#ABC`, host: `redis`
  - `redis://user:pass@localhost:6379/0` → standard format (unchanged)
  - `redis://:pass%23word@localhost:6379/0` → URL-encoded password handling
  - `redis://localhost:6379/0` → no password format

Actual Behavior

  The fix should handle all these scenarios correctly:
  - `redis://!asdfsfd#ABC/redis:6379/1` → password: `!asdfsfd` and host `localhost`
Originally created by @Sn0rt on GitHub (Jul 28, 2025). ### Self Checks - [x] I have read the [Contributing Guide](https://github.com/langgenius/dify/blob/main/CONTRIBUTING.md) and [Language Policy](https://github.com/langgenius/dify/issues/1542). - [x] This is only for bug report, if you would like to ask a question, please head to [Discussions](https://github.com/langgenius/dify/discussions/categories/general). - [x] I have searched for existing issues [search for existing issues](https://github.com/langgenius/dify/issues), including closed ones. - [x] I confirm that I am using English to submit this report, otherwise it will be closed. - [x] 【中文用户 & Non English User】请使用英语提交,否则会被关闭 :) - [x] Please do not modify this template :) and fill in all the required fields. ### Dify version not applicable ### Cloud or Self Hosted Self Hosted (Docker) ### Steps to reproduce Celery uses kombu's parse_url method to parse URLs. This internal method supports parsing passwords containing special characters (requiring manual URL encoding). However, the monitor task implemented in api/schedule/queue_monitor_task.py simply performs URL parsing. If the password contains a #, the parsing will fail. ```python In [1]: from urllib.parse import urlparse In [2]: urlparse("redis://admin:complex%23pass%40word@127.0.0.1:6379/0") Out[2]: ParseResult(scheme='redis', netloc='admin:complex%23pass%40word@127.0.0.1:6379', path='/0', params='', query='', fragment='') In [3]: parsed = urlparse("redis://admin:complex%23pass%40word@127.0.0.1:6379/0") In [4]: parsed Out[4]: ParseResult(scheme='redis', netloc='admin:complex%23pass%40word@127.0.0.1:6379', path='/0', params='', query='', fragment='') In [5]: parsed.hostname Out[5]: '127.0.0.1' In [6]: parsed.password Out[6]: 'complex%23pass%40word' In [7]: parsed = urlparse("redis://admin:complex#123@127.0.0.1:6379/0") In [8]: parsed.password In [9]: ## Current Code (Broken) ``` ```python # In api/schedule/queue_monitor_task.py parsed = urlparse(celery_broker_url) host = parsed.hostname or "localhost" port = parsed.port or 6379 password = parsed.password or None redis_db = parsed.path.strip("/") or "1" ``` ## Impact - Users with Redis passwords containing special characters cannot connect - Silent connection failures that are hard to debug - Affects queue monitoring functionality ## Proposed Solution Have users URL-encode their passwords in advance if the password include special chart. I have checked Celery and not found the same issue (this support url encoded url), so this seems to be the recommended solution. Of course, another option is to use multiple environment variables to split the BROKER_URL used by Celery into pre-determined independent variables, such as CELERY_BROKER_USERNAME and CELERY_BROKER_PASSWORD. ```python celery_app = Celery( app.name, task_cls=FlaskTask, broker=dify_config.CELERY_BROKER_URL, backend=dify_config.CELERY_BACKEND, task_ignore_result=True, ) ``` ```python >>> kombu.utils.url.parse_url("redis://admin:complex%23pass%40word@127.0.0.1:6379/0") {'transport': 'redis', 'hostname': '127.0.0.1', 'port': 6379, 'userid': 'admin', 'password': 'complex#pass@word', 'virtual_host': '0'} ``` ### ✔️ Expected Behavior The fix should handle all these scenarios correctly: - `redis://!asdfsfd#ABC/redis:6379/1` → password: `!asdfsfd#ABC`, host: `redis` - `redis://user:pass@localhost:6379/0` → standard format (unchanged) - `redis://:pass%23word@localhost:6379/0` → URL-encoded password handling - `redis://localhost:6379/0` → no password format ### ❌ Actual Behavior The fix should handle all these scenarios correctly: - `redis://!asdfsfd#ABC/redis:6379/1` → password: `!asdfsfd` and host `localhost`
yindo closed this issue 2026-02-21 19:23:01 -05:00
Sign in to join this conversation.
1 Participants
Notifications
Due Date
No due date set.
Dependencies

No dependencies set.

Reference: langgenius/dify#15714