# 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!**
