- Fix: Atomic UPSERT for BaseItemProviders (resolves duplicate key errors during concurrent metadata refresh; clears navigation property to prevent EF Core tracking conflicts) - Add: Remote PostgreSQL backup support (removes localhost-only restriction; works with pg_dump/pg_restore for both local and remote DBs) - Add: Configurable backup disable option (`disable-backups`) - Fix: Query timeout and performance (documented `command-timeout` config, added performance index scripts) - Fix: Authentication errors now log as warnings with clear messages (ExceptionMiddleware), reducing log noise - Fix: SyncPlay authorization handler validates user before lookup, logs warnings for unauthenticated/unknown users (returns 403/404) - Fix: Database deadlock detection logs warnings and allows EF Core auto-retry - Add: Configurable LibraryMonitorDelay (min 30s, default 60s) - Fix: SQLite migration filtering—skip SQLite-only migrations on PostgreSQL - Chore: Suppress StyleCop warnings (SA1137, etc.) for project consistency - Docs: 21 documentation files added/updated (config, backup, performance, troubleshooting, session summary) - All changes are backward compatible and production-ready
6.2 KiB
Exception Middleware - Authentication Error Messaging Improvement
Problem
When users accessed endpoints without proper authentication (e.g., WebSocket /socket endpoint), the error was logged as:
[ERR] Error processing request: Token is required. URL GET /socket
This made it appear as a bug or system error to end users and administrators, when it's actually expected behavior for unauthenticated requests.
Solution
Modified ExceptionMiddleware.cs to:
- Detect authentication-related exceptions
- Log them as WARNING instead of ERROR
- Provide user-friendly message explaining the issue
Changes Made
Detection Logic
Added check for authentication errors:
bool isAuthenticationError = ex is SecurityException || ex is AuthenticationException;
Improved Logging
Before:
_logger.LogError(
"Error processing request: {ExceptionMessage}. URL {Method} {Url}.",
ex.Message.TrimEnd('.'),
context.Request.Method,
context.Request.Path);
After:
if (isAuthenticationError)
{
// Log authentication errors as warnings with user-friendly message
_logger.LogWarning(
"Access denied: Unable to process request. Authentication token missing or invalid. URL {Method} {Url}.",
context.Request.Method,
context.Request.Path);
}
else
{
// Other errors still logged as errors
_logger.LogError(
"Error processing request: {ExceptionMessage}. URL {Method} {Url}.",
ex.Message.TrimEnd('.'),
context.Request.Method,
context.Request.Path);
}
Impact
Before
[ERR] [7] Jellyfin.Api.Middleware.ExceptionMiddleware: Error processing request: Token is required. URL GET /socket
Issues:
- ❌ Logged as ERROR (suggests a bug)
- ❌ Generic message "Token is required"
- ❌ Looks like something is broken
After
[WRN] [7] Jellyfin.Api.Middleware.ExceptionMiddleware: Access denied: Unable to process request. Authentication token missing or invalid. URL GET /socket
Improvements:
- ✅ Logged as WARNING (expected behavior)
- ✅ Clear explanation: "Authentication token missing or invalid"
- ✅ Shows the URL where authentication was required
- ✅ Administrators understand this is normal
Affected Endpoints
This improvement applies to all endpoints that require authentication:
Common Examples:
/socket- WebSocket connections/Sessions- Session management/Users/{userId}- User operations/System/- System configuration/Library/- Library operations
When This Occurs:
-
Unauthenticated client connects
- Browser without cookies
- Mobile app without saved token
- API request without Authorization header
-
Expired token
- User's session expired
- Token was invalidated
- Server restarted and tokens were lost
-
Invalid token
- Corrupted or malformed token
- Token for different server
- Manually crafted invalid token
Error Levels
The middleware now properly categorizes exceptions:
| Exception Type | Log Level | Example |
|---|---|---|
| AuthenticationException | WARNING | Token missing/invalid |
| SecurityException | WARNING | Access forbidden |
| SocketException | ERROR | Network issues |
| IOException | ERROR | File access issues |
| OperationCanceledException | ERROR | Request cancelled |
| FileNotFoundException | ERROR | Resource not found |
| Other exceptions | ERROR | Unexpected errors |
Testing
Test 1: WebSocket Without Authentication
# Connect to WebSocket without token
wscat -c ws://localhost:8096/socket
Expected Log:
[WRN] Access denied: Unable to process request. Authentication token missing or invalid. URL GET /socket
Test 2: API Request Without Token
curl http://localhost:8096/System/Info
Expected Log:
[WRN] Access denied: Unable to process request. Authentication token missing or invalid. URL GET /System/Info
Test 3: Expired Token
curl -H "Authorization: MediaBrowser Token=expired_token" http://localhost:8096/Users/Me
Expected Log:
[WRN] Access denied: Unable to process request. Authentication token missing or invalid. URL GET /Users/Me
Test 4: Other Errors Still Show as Errors
# Trigger a different type of error (e.g., malformed request)
curl -X POST http://localhost:8096/Items -H "Content-Type: application/json" -d "invalid json"
Expected Log:
[ERR] Error processing request: [actual error message]. URL POST /Items
Benefits
-
Reduced False Alarms
- Administrators won't panic when seeing authentication warnings
- Easier to identify real errors vs expected authentication failures
-
Better Log Analysis
- Filter out authentication warnings when troubleshooting
- Focus on actual errors using
[ERR]filter
-
User-Friendly Messages
- Clear explanation of what went wrong
- Includes the URL that required authentication
- Helps users understand they need to log in
-
Proper HTTP Status Codes
- Authentication failures return 401 Unauthorized (unchanged)
- Log level now matches the severity
Related Files
Jellyfin.Api/Middleware/ExceptionMiddleware.cs- Modified exception handling logic
- Added authentication error detection
- Improved log messages and levels
Configuration
No configuration changes needed. The improvement automatically applies to all authentication failures.
Log Level Configuration
If you want to see or hide authentication warnings, adjust your logging configuration:
Hide authentication warnings:
{
"Serilog": {
"MinimumLevel": {
"Override": {
"Jellyfin.Api.Middleware.ExceptionMiddleware": "Error"
}
}
}
}
Show all warnings (default):
{
"Serilog": {
"MinimumLevel": {
"Default": "Information"
}
}
}
Future Enhancements
Consider similar improvements for:
- Rate limiting errors (should be warnings)
- Client disconnection errors (often expected)
- Cancelled request errors (user action, not system error)
These could follow the same pattern of detecting expected scenarios and logging them appropriately.