When OAuth client secrets contain special characters like +, authentication fails with invalid_client: Client authentication failed
Root Cause
In application/x-www-form-urlencoded POST requests, the + character is interpreted as a space. The client_secret_post method doesn't URL-encode the secret value before sending it to the IdP.
Applied urllib.parse.quote() with safe='' to ALL OAuth client secrets:
OAUTH_CLIENT_SECRET (OIDC/OpenID Connect)
GOOGLE_CLIENT_SECRET
MICROSOFT_CLIENT_SECRET
GITHUB_CLIENT_SECRET
FEISHU_CLIENT_SECRET
Using safe='' ensures ALL special characters are encoded (e.g., + becomes %2B)
Test
The fix handles:
Empty/None values - preserved as-is
Normal secrets - no change in behavior
Secrets with special chars - now properly encoded
Example: helloworld+1234 → sent as helloworld%2B1234 to IdP
Checklist
Minimal fix focused on the issue
No new dependencies added (using stdlib urllib.parse)
Backward compatible (doesn't break existing secrets without special chars)
Applied to all OAuth providers consistently
🔄 This issue represents a GitHub Pull Request. It cannot be merged through Gitea due to API limitations.
## 📋 Pull Request Information
**Original PR:** https://github.com/open-webui/open-webui/pull/20744
**Author:** [@YuriNachos](https://github.com/YuriNachos)
**Created:** 1/17/2026
**Status:** ❌ Closed
**Base:** `main` ← **Head:** `fix-oauth-client-secret-url-encoding`
---
### 📝 Commits (4)
- [`f84aad5`](https://github.com/open-webui/open-webui/commit/f84aad5f141ab769d4b75628f576c89c9ff88db9) fix: handle None value for model capabilities in builtin_tools check
- [`0d4898f`](https://github.com/open-webui/open-webui/commit/0d4898fa40798e396c4deb2f9cc71b0b7d54baf4) fix: handle None value for model capabilities in file_context check
- [`9772be0`](https://github.com/open-webui/open-webui/commit/9772be02cc1d4b4153a76fd15a12d07d47f8eb66) fix: handle None value for capabilities in get_model_capability helper
- [`3d404ff`](https://github.com/open-webui/open-webui/commit/3d404ff87cac3d257c56ed1ef198ed5b8c142ecf) fix: URL-encode OAuth client secrets to handle special characters
### 📊 Changes
**3 files changed** (+11 additions, -13 deletions)
<details>
<summary>View changed files</summary>
📝 `backend/open_webui/config.py` (+6 -6)
📝 `backend/open_webui/utils/middleware.py` (+4 -6)
📝 `backend/open_webui/utils/tools.py` (+1 -1)
</details>
### 📄 Description
## Summary
Fixes #20733
When OAuth client secrets contain special characters like `+`, authentication fails with `invalid_client: Client authentication failed`
## Root Cause
In `application/x-www-form-urlencoded` POST requests, the `+` character is interpreted as a space. The `client_secret_post` method doesn't URL-encode the secret value before sending it to the IdP.
Example: `helloworld+1234` becomes `helloworld 1234` (with space)
## Changes
- Modified `backend/open_webui/config.py`
- Added `quote as urlquote` import from `urllib.parse`
- Applied `urllib.parse.quote()` with `safe=''` to ALL OAuth client secrets:
- `OAUTH_CLIENT_SECRET` (OIDC/OpenID Connect)
- `GOOGLE_CLIENT_SECRET`
- `MICROSOFT_CLIENT_SECRET`
- `GITHUB_CLIENT_SECRET`
- `FEISHU_CLIENT_SECRET`
- Using `safe=''` ensures ALL special characters are encoded (e.g., `+` becomes `%2B`)
## Test
The fix handles:
- Empty/None values - preserved as-is
- Normal secrets - no change in behavior
- Secrets with special chars - now properly encoded
Example: `helloworld+1234` → sent as `helloworld%2B1234` to IdP
## Checklist
- [x] Minimal fix focused on the issue
- [x] No new dependencies added (using stdlib urllib.parse)
- [x] Backward compatible (doesn't break existing secrets without special chars)
- [x] Applied to all OAuth providers consistently
---
<sub>🔄 This issue represents a GitHub Pull Request. It cannot be merged through Gitea due to API limitations.</sub>
Blocking a user prevents them from interacting with repositories, such as opening or commenting on pull requests or issues. Learn more about blocking a user.
📋 Pull Request Information
Original PR: https://github.com/open-webui/open-webui/pull/20744
Author: @YuriNachos
Created: 1/17/2026
Status: ❌ Closed
Base:
main← Head:fix-oauth-client-secret-url-encoding📝 Commits (4)
f84aad5fix: handle None value for model capabilities in builtin_tools check0d4898ffix: handle None value for model capabilities in file_context check9772be0fix: handle None value for capabilities in get_model_capability helper3d404fffix: URL-encode OAuth client secrets to handle special characters📊 Changes
3 files changed (+11 additions, -13 deletions)
View changed files
📝
backend/open_webui/config.py(+6 -6)📝
backend/open_webui/utils/middleware.py(+4 -6)📝
backend/open_webui/utils/tools.py(+1 -1)📄 Description
Summary
Fixes #20733
When OAuth client secrets contain special characters like
+, authentication fails withinvalid_client: Client authentication failedRoot Cause
In
application/x-www-form-urlencodedPOST requests, the+character is interpreted as a space. Theclient_secret_postmethod doesn't URL-encode the secret value before sending it to the IdP.Example:
helloworld+1234becomeshelloworld 1234(with space)Changes
backend/open_webui/config.pyquote as urlquoteimport fromurllib.parseurllib.parse.quote()withsafe=''to ALL OAuth client secrets:OAUTH_CLIENT_SECRET(OIDC/OpenID Connect)GOOGLE_CLIENT_SECRETMICROSOFT_CLIENT_SECRETGITHUB_CLIENT_SECRETFEISHU_CLIENT_SECRETsafe=''ensures ALL special characters are encoded (e.g.,+becomes%2B)Test
The fix handles:
Example:
helloworld+1234→ sent ashelloworld%2B1234to IdPChecklist
🔄 This issue represents a GitHub Pull Request. It cannot be merged through Gitea due to API limitations.