# WebSocket "Token is required" Error - Not a Bug! **Error Message:** `Token is required. URL GET /socket` **Location:** `Jellyfin.Api.Middleware.ExceptionMiddleware` **Status:** ✅ Expected Behavior (Not a Bug) --- ## What This Error Means ### The Message ``` [WRN] Jellyfin.Api.Middleware.ExceptionMiddleware: Error processing request: Token is required. URL GET /socket ``` ### What's Happening 1. A client (web browser, mobile app, etc.) is trying to connect to the WebSocket endpoint 2. The WebSocket endpoint `/socket` **requires authentication** 3. The client didn't provide a valid authentication token 4. Jellyfin correctly rejects the connection **This is SECURITY WORKING AS INTENDED** ✅ --- ## Why WebSockets Require Authentication ### Code Location **File:** `Emby.Server.Implementations/HttpServer/WebSocketManager.cs` **Method:** `WebSocketRequestHandler()` ```csharp public async Task WebSocketRequestHandler(HttpContext context) { // Authenticate the request var authorizationInfo = await _authService.Authenticate(context.Request).ConfigureAwait(false); // Reject if not authenticated if (!authorizationInfo.IsAuthenticated) { throw new SecurityException("Token is required"); } // Continue with WebSocket connection... } ``` ### Why Authentication Is Required 1. **Real-Time Updates** - WebSockets send real-time events about: - Library changes - Playback status - User activities - System notifications 2. **Personal Data** - WebSocket messages contain: - User-specific information - Viewing history - Preferences - Session data 3. **Security** - Without authentication: - Anyone could listen to events - Privacy violation - Potential data leak --- ## Common Causes ### 1. Browser Extension or Developer Tools ⚠️ **Scenario:** Browser trying to auto-connect WebSocket ```javascript // Browser dev tools or extension var ws = new WebSocket('ws://localhost:8096/socket'); // ❌ No token provided → "Token is required" error ``` **Solution:** Ignore - this is external tools testing ### 2. Web Client Not Sending Token **Scenario:** Jellyfin web client not properly authenticated **Possible causes:** - Session expired - Cookie cleared - Fresh installation without login **Solution:** Log in to web UI at http://localhost:8096 ### 3. Third-Party Client Issues **Scenario:** Mobile app or third-party client with authentication issues **Solution:** - Re-authenticate in the client - Check client API token configuration - Update client to latest version ### 4. Development/Testing Scripts **Scenario:** Testing WebSocket without authentication **Solution:** Add proper authentication: ```javascript // Correct WebSocket connection with token const accessToken = 'your-jellyfin-api-token'; const ws = new WebSocket(`ws://localhost:8096/socket?api_key=${accessToken}`); ``` --- ## How to Fix (If Needed) ### Option 1: Ignore the Error (Recommended) ✅ **When:** Error appears occasionally and doesn't affect functionality **Action:** Nothing - this is normal **Reason:** - Browsers test WebSocket connections - Extensions probe endpoints - Development tools auto-connect - These are expected failed attempts **In startup.json or appsettings.json:** ```json { "Serilog": { "MinimumLevel": { "Override": { "Jellyfin.Api.Middleware.ExceptionMiddleware": "Error" } } } } ``` This reduces warning noise while keeping actual errors visible. --- ### Option 2: Check Web Client Authentication **When:** Error happens every time you load web UI **Steps:** 1. **Clear browser cache and cookies** ``` Chrome: Settings → Privacy → Clear browsing data Firefox: Settings → Privacy → Clear Data ``` 2. **Access web UI** ``` http://localhost:8096 ``` 3. **Log in again** - Enter username/password - Client will get new token - WebSocket should connect successfully 4. **Verify in browser console** ```javascript // F12 → Console // Should see: "WebSocket connection established" ``` --- ### Option 3: Check Startup Configuration **File:** `startup.json` or environment configuration **Verify:** ```json { "EnableRemoteAccess": true, "RequireHttps": false, // For local development "BaseUrl": "", "HttpServerPortNumber": 8096 } ``` **Common issues:** - BaseUrl misconfigured - RequireHttps forcing HTTP redirect - Port conflicts --- ## Debugging WebSocket Connections ### Check Browser Console **Open Developer Tools (F12):** ```javascript // Console tab - look for: WebSocket connection to 'ws://localhost:8096/socket' failed: Error during WebSocket handshake: Unexpected response code: 401 ``` **Network tab:** - Look for `/socket` request - Check status code - Check headers (should have Authorization or api_key) ### Check Jellyfin Logs **File:** `log/log_*.txt` **Good connection:** ``` [INF] WS 127.0.0.1 request [INF] WS 127.0.0.1 closed ``` **Failed connection:** ``` [WRN] Error processing request: Token is required. URL GET /socket ``` --- ## When to Worry ### ⚠️ Investigate If: 1. **Constant errors** - Every few seconds 2. **Affects functionality** - Real-time updates not working 3. **After fresh install** - Can't connect at all 4. **All clients failing** - Not just one browser ### ✅ Ignore If: 1. **Occasional** - Happens rarely 2. **No impact** - Everything works fine 3. **Development only** - Testing/debugging 4. **Browser extensions** - External tools probing --- ## Security Implications ### ✅ Good Security Practice The "Token is required" error shows that: - ✅ Authentication is enforced - ✅ Unauthorized access is blocked - ✅ Security middleware is working - ✅ WebSocket endpoints are protected ### If You Disable Authentication (DON'T!) **Never do this:** ```csharp // BAD - Don't remove authentication check if (!authorizationInfo.IsAuthenticated) { // Don't comment this out! // throw new SecurityException("Token is required"); } ``` **Why not:** - Anyone can connect to WebSocket - Privacy violation - Data leak - Security vulnerability --- ## Client Integration Guide ### For Developers Building Jellyfin Clients **Correct WebSocket connection:** ```javascript // Step 1: Get API token (after login) const accessToken = jellyfinApi.getAccessToken(); // Step 2: Connect with token const wsUrl = `ws://server:8096/socket?api_key=${accessToken}`; const ws = new WebSocket(wsUrl); // Step 3: Handle connection ws.onopen = () => console.log('Connected'); ws.onmessage = (event) => console.log('Message:', event.data); ws.onerror = (error) => console.error('Error:', error); ``` **Alternative (Authorization header):** ```javascript const ws = new WebSocket('ws://server:8096/socket'); ws.onopen = () => { // Send authentication message ws.send(JSON.stringify({ MessageType: 'Authenticate', Data: accessToken })); }; ``` --- ## Configuration Options ### Option A: Log Level Adjustment (Recommended) **Reduce noise from failed connection attempts:** **File:** `Jellyfin.Server/appsettings.json` or `startup.json` ```json { "Serilog": { "MinimumLevel": { "Default": "Information", "Override": { "Jellyfin.Api.Middleware.ExceptionMiddleware": "Error", "Microsoft.AspNetCore.Diagnostics.ExceptionHandlerMiddleware": "Error" } } } } ``` **Effect:** - Security exceptions logged at Error level only - Reduces log noise - Still captures important errors ### Option B: Custom WebSocket Authentication **If you need different auth logic (not recommended):** Modify `WebSocketManager.cs`: ```csharp // Allow anonymous for specific scenarios (NOT RECOMMENDED) if (context.Request.Path == "/socket/anonymous") { // Skip authentication } ``` --- ## Common Scenarios ### Scenario 1: Browser Dev Tools **What happens:** - Open F12 dev tools - Browser auto-tests WebSocket endpoint - No token provided - Error logged **Solution:** Ignore - normal browser behavior --- ### Scenario 2: Fresh Installation **What happens:** - First run of Jellyfin - No users logged in yet - Web UI tries to connect WebSocket - Error logged until first login **Solution:** Complete setup wizard and log in --- ### Scenario 3: Session Timeout **What happens:** - User logged in previously - Session expired (default: 24 hours) - WebSocket reconnect fails - Error logged **Solution:** User re-authenticates automatically or manually --- ### Scenario 4: Reverse Proxy Issues **What happens:** - Jellyfin behind reverse proxy (nginx, Apache) - WebSocket headers not forwarded correctly - Token not reaching Jellyfin - Error logged **Solution:** Configure reverse proxy to forward WebSocket headers **nginx example:** ```nginx location /socket { proxy_pass http://jellyfin:8096; proxy_http_version 1.1; proxy_set_header Upgrade $http_upgrade; proxy_set_header Connection "Upgrade"; proxy_set_header X-Real-IP $remote_addr; proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for; proxy_set_header X-Forwarded-Proto $scheme; proxy_set_header X-Forwarded-Host $host; } ``` --- ## Monitoring ### Normal Operation **Expected log pattern:** ``` [INF] WS 192.168.1.100 request [INF] WS 192.168.1.100 closed [INF] WS 192.168.1.101 request ``` **Occasional failed attempts:** ``` [WRN] Error processing request: Token is required. URL GET /socket ``` ↑ This is fine if occasional ### Problem Indicators **Constant errors (every few seconds):** ``` [WRN] Error processing request: Token is required. URL GET /socket [WRN] Error processing request: Token is required. URL GET /socket [WRN] Error processing request: Token is required. URL GET /socket ... ``` ↑ Investigate client authentication --- ## Summary **Error:** `Token is required. URL GET /socket` **Cause:** Unauthenticated WebSocket connection attempt **Status:** ✅ Expected behavior (security working) **Action Required:** None (unless affecting functionality) ### When to Ignore ✅ - Occasional occurrence - No functionality impact - Normal operation otherwise ### When to Investigate ⚠️ - Constant/frequent errors - Real-time updates not working - After fresh install or configuration change --- ## Related Files - `WebSocketHandlerMiddleware.cs` - Middleware entry point - `WebSocketManager.cs` - Authentication check - `ExceptionMiddleware.cs` - Error logging --- ## Quick Checklist If this error concerns you, check: - [ ] Can you access web UI? (http://localhost:8096) - [ ] Can you log in? - [ ] Do real-time updates work? - [ ] Is this happening constantly or occasionally? - [ ] Any reverse proxy in use? If all above are OK → **Ignore the error** ✅ --- **Conclusion:** This is a security feature working correctly. The error logs unauthenticated connection attempts, which is expected and normal in web environments. ✅ **No fix needed - security is working as designed!**