Describe the bug
After a successful OIDC authentication and user linking (confirmed in server logs, no errors), the browser stays stuck on "Logging in..." indefinitely and never completes the redirect into the web UI.
The injected script's token-handoff iframe is built with a double slash in its src URL, causing the request to 404. Inspecting the DOM during the hang shows:
Note the double slash before web/index.html. Browser console confirms:
Failed to load resource: the server responded with a status of 404 () — index.html:1
Since the iframe never loads the real Jellyfin web client, the postMessage token handoff never completes, leaving the user stuck on "Logging in...".
To Reproduce
Configure the OIDC plugin with a provider (Pocket ID in my case) and a working callback/start URL.
Log in via the "Sign in with [Provider]" button on the Jellyfin login page.
Complete authentication with the IdP and get redirected back to /oidc/redirect/<ProviderName>.
Observe the page hangs on "Logging in..." indefinitely.
Open DevTools → inspect the DOM for #iframe-index-html and see the double-slash src, and check Console for the resulting 404.
Expected behavior
The iframe src should resolve to https://jellyfin.example.com/web/index.html (single slash), the iframe should load successfully, and the token handoff should complete, redirecting the user into the app.
Plugin Version: currently on 6.0.0.1 but also tested on 6.0.0.3, 6.0.0.4 is not on as an option to install.
Additional context
Server-side logs show the OIDC flow completing without error up through user linking:
[INF] OIDC Controller initialized
[INF] Processing response.
[WRN] Extracted username "austinsama12"
[INF] OIDC user link doesn't exist, linking... user: "austinsama12"(10e584a2-1ded-49b8-b274-8e5da700b659)
[INF] User is linked to OIDC Provider "austinsama12" (...) to JellyFin user "austinsama12"(...): "OIDC User is already linked in this provider"
[INF] Is request linking: [False]
Confirmed the bug is client-side, in how the iframe src is constructed from the base URL. Manually removing the extra slash from the injected JS resolves the issue and login completes successfully. Also confirmed the "Published Server URL" and "Base URL" fields in Dashboard → Networking have no trailing slash, and the Caddy reverse proxy config has no trailing-slash rule, so the double slash originates from the plugin's own URL construction, not server/proxy config.
**Describe the bug**
After a successful OIDC authentication and user linking (confirmed in server logs, no errors), the browser stays stuck on "Logging in..." indefinitely and never completes the redirect into the web UI.
The injected script's token-handoff iframe is built with a double slash in its `src` URL, causing the request to 404. Inspecting the DOM during the hang shows:
```html
<iframe id="iframe-index-html" title="Something" class="docs-texteventtarget"
sandbox="allow-same-origin allow-forms allow-scripts"
src="https://jellyfin.example.com//web/index.html"
style="position:absolute;width:0;height:0;border:0;">
</iframe>
```
Note the double slash before `web/index.html`. Browser console confirms:
> Failed to load resource: the server responded with a status of 404 () — index.html:1
Since the iframe never loads the real Jellyfin web client, the postMessage token handoff never completes, leaving the user stuck on "Logging in...".
**To Reproduce**
1. Configure the OIDC plugin with a provider (Pocket ID in my case) and a working callback/start URL.
2. Log in via the "Sign in with [Provider]" button on the Jellyfin login page.
3. Complete authentication with the IdP and get redirected back to `/oidc/redirect/<ProviderName>`.
4. Observe the page hangs on "Logging in..." indefinitely.
5. Open DevTools → inspect the DOM for `#iframe-index-html` and see the double-slash `src`, and check Console for the resulting 404.
**Expected behavior**
The iframe `src` should resolve to `https://jellyfin.example.com/web/index.html` (single slash), the iframe should load successfully, and the token handoff should complete, redirecting the user into the app.
**Screenshots**
<img width="1439" alt="chrome_rcSd1TKa50.png" src="attachments/735d5dcb-5a70-4de4-b95e-57df14bad4f9">
**Configuration**
https://bin.thecattery.de/?12481e8808af8822#HQAfqNNGvDks1XWbKXxGtA3vHUPHB21NKTzUB9NTeoC8
https://paste.d-ku.de/?94c29ed740d4d3cb#7aUo8CainnxweYYPEToKVCCY8E8yNaMPtyWLodZ1x4ZY (if the above doesn't work)
**Versions:**
- OS: Proxmox VE 9.2.20, bare-metal (no Docker)
- Browser: Chrome, Firefox (reproduced on both)
- Jellyfin Version: 10.11.11
- Plugin Version: currently on 6.0.0.1 but also tested on 6.0.0.3, 6.0.0.4 is not on as an option to install.
**Additional context**
Server-side logs show the OIDC flow completing without error up through user linking:
```
[INF] OIDC Controller initialized
[INF] Processing response.
[WRN] Extracted username "austinsama12"
[INF] OIDC user link doesn't exist, linking... user: "austinsama12"(10e584a2-1ded-49b8-b274-8e5da700b659)
[INF] User is linked to OIDC Provider "austinsama12" (...) to JellyFin user "austinsama12"(...): "OIDC User is already linked in this provider"
[INF] Is request linking: [False]
```
Confirmed the bug is client-side, in how the iframe `src` is constructed from the base URL. Manually removing the extra slash from the injected JS resolves the issue and login completes successfully. Also confirmed the "Published Server URL" and "Base URL" fields in Dashboard → Networking have no trailing slash, and the Caddy reverse proxy config has no trailing-slash rule, so the double slash originates from the plugin's own URL construction, not server/proxy config.
punyURL is a System.UriBuilder, and UriBuilder.ToString() includes a trailing slash when no path is set (e.g. https://jellyfin.example.com/). Concatenating /web/index.html onto that produces a double slash:
This mirrors the same .trimEnd('/')+'/' pattern already used for punyURL in OIDC-Auth-auth.html (commit 525a417), so it would be consistent with existing handling elsewhere in the codebase. This also explains why the bug reproduced on every version tried including 6.0.0.1, since that commit only touched the JS retry path in OIDC-Auth-auth.html, not this server-side HTML generation in WebResponse.cs.
**Update, found the root cause.**
The bug is in [`WebResponse.cs` line 35](https://gitea.narnian.us/lordwelch/jellyfin-plugin-oidc/src/commit/525a41726aa2f13ee0670a61fb582445c320690f/Jellyfin.Plugin.OIDC-Auth/WebResponse.cs#L35):
```csharp
.Replace("src=\"index.html\"", "src=\"" + punyURL.ToString() + "/web/index.html\"");
```
`punyURL` is a `System.UriBuilder`, and `UriBuilder.ToString()` includes a trailing slash when no path is set (e.g. `https://jellyfin.example.com/`). Concatenating `/web/index.html` onto that produces a double slash:
```
https://jellyfin.example.com/ + /web/index.html
= https://jellyfin.example.com//web/index.html
```
This 404s and breaks the iframe-based token handoff, which is the actual cause of the "Logging in..." hang described above.
Suggested fix, one line:
```csharp
.Replace("src=\"index.html\"", "src=\"" + punyURL.ToString().TrimEnd('/') + "/web/index.html\"");
```
This mirrors the same `.trimEnd('/')+'/'` pattern already used for `punyURL` in `OIDC-Auth-auth.html` (commit 525a417), so it would be consistent with existing handling elsewhere in the codebase. This also explains why the bug reproduced on every version tried including 6.0.0.1, since that commit only touched the JS retry path in `OIDC-Auth-auth.html`, not this server-side HTML generation in `WebResponse.cs`.
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.
Describe the bug
After a successful OIDC authentication and user linking (confirmed in server logs, no errors), the browser stays stuck on "Logging in..." indefinitely and never completes the redirect into the web UI.
The injected script's token-handoff iframe is built with a double slash in its
srcURL, causing the request to 404. Inspecting the DOM during the hang shows:Note the double slash before
web/index.html. Browser console confirms:Since the iframe never loads the real Jellyfin web client, the postMessage token handoff never completes, leaving the user stuck on "Logging in...".
To Reproduce
/oidc/redirect/<ProviderName>.#iframe-index-htmland see the double-slashsrc, and check Console for the resulting 404.Expected behavior
The iframe
srcshould resolve tohttps://jellyfin.example.com/web/index.html(single slash), the iframe should load successfully, and the token handoff should complete, redirecting the user into the app.Screenshots

Configuration
https://bin.thecattery.de/?12481e8808af8822#HQAfqNNGvDks1XWbKXxGtA3vHUPHB21NKTzUB9NTeoC8
https://paste.d-ku.de/?94c29ed740d4d3cb#7aUo8CainnxweYYPEToKVCCY8E8yNaMPtyWLodZ1x4ZY (if the above doesn't work)
Versions:
Additional context
Server-side logs show the OIDC flow completing without error up through user linking:
Confirmed the bug is client-side, in how the iframe
srcis constructed from the base URL. Manually removing the extra slash from the injected JS resolves the issue and login completes successfully. Also confirmed the "Published Server URL" and "Base URL" fields in Dashboard → Networking have no trailing slash, and the Caddy reverse proxy config has no trailing-slash rule, so the double slash originates from the plugin's own URL construction, not server/proxy config.Does
525a41726afix this?Update, found the root cause.
The bug is in
WebResponse.csline 35:punyURLis aSystem.UriBuilder, andUriBuilder.ToString()includes a trailing slash when no path is set (e.g.https://jellyfin.example.com/). Concatenating/web/index.htmlonto that produces a double slash:This 404s and breaks the iframe-based token handoff, which is the actual cause of the "Logging in..." hang described above.
Suggested fix, one line:
This mirrors the same
.trimEnd('/')+'/'pattern already used forpunyURLinOIDC-Auth-auth.html(commit525a417), so it would be consistent with existing handling elsewhere in the codebase. This also explains why the bug reproduced on every version tried including 6.0.0.1, since that commit only touched the JS retry path inOIDC-Auth-auth.html, not this server-side HTML generation inWebResponse.cs.