- Comment out CORS headers in nginx.conf to fix button input blocking - Add WAL enable job for Jellyfin to resolve database locking issues - Include comprehensive troubleshooting documentation 🤖 Generated with [Claude Code](https://claude.com/claude-code) Co-Authored-By: Claude <noreply@anthropic.com>
11 KiB
Jellyfin Error Analysis and Recommendations
Overview
Analysis of Jellyfin errors found in the media namespace logs, with recommendations for resolution.
Issues Identified
1. SQLite Database Locking Errors (CRITICAL)
Error Messages:
[04:28:37] [ERR] Microsoft.Data.Sqlite.SqliteException (0x80004005): SQLite Error 5: 'database is locked'.
[09:00:00] [ERR] SQLite Error 5: 'database is locked For more information on this error code see https://www.sqlite.org/rescode.html'.
Impact:
- Prevents metadata updates during library scans
- Causes API request failures (GET /Items)
- Occurs when database optimization runs concurrently with library operations
Root Cause: SQLite's default locking mechanism allows only one writer at a time. The errors occur when:
- Database optimization task runs (VACUUM operation)
- Library scan attempts to update metadata simultaneously
- Both operations try to write to the database
Frequency:
- Database optimization runs approximately every 6 hours
- Library scans run every 12 hours
- Conflicts occur when these overlap
2. Audio Normalization Failures (MODERATE)
Error Message:
[04:24:54] [ERR] Emby.Server.Implementations.ScheduledTasks.Tasks.AudioNormalizationTask: Failed to find LUFS value in output
Impact:
- Audio normalization task cannot measure loudness
- Prevents automatic volume leveling across music library
- Task completes without performing any normalization
Root Cause: The LUFS (Loudness Units relative to Full Scale) detection failure suggests:
- FFmpeg may be missing required audio analysis filters
- Audio files may have incompatible formats
- FFmpeg output parsing may be failing
Frequency:
- Runs daily at 04:24 (during scheduled tasks)
- Consistently fails to find LUFS values
3. Library Folder Warnings (LOW PRIORITY)
Warning Messages:
[04:25:47] [WRN] Library folder /ebooks is inaccessible or empty, skipping
[04:25:47] [WRN] Library folder /config/data/playlists is inaccessible or empty, skipping
Impact:
- Minimal - warnings only
- No functional issues if these folders are intentionally empty
- Causes log noise
Root Cause:
- Library folders are configured but:
/ebooksfolder doesn't exist or is empty/config/data/playlistsfolder is empty
- Jellyfin skips these during library scans
Recommendations
Priority 1: Fix Database Locking Issues
Option A: Enable WAL Mode (RECOMMENDED)
WAL (Write-Ahead Logging) mode allows concurrent readers during writes, reducing lock contention.
Implementation:
- Create a job to enable WAL mode:
Create file: /storage/emulated/0/Download/nv/jellyfin-wal-enable.yaml
apiVersion: batch/v1
kind: Job
metadata:
name: jellyfin-enable-wal
namespace: media
spec:
ttlSecondsAfterFinished: 600
template:
spec:
restartPolicy: Never
containers:
- name: enable-wal
image: alpine:latest
command:
- sh
- -c
- |
apk add --no-cache sqlite
echo "Enabling WAL mode on jellyfin.db..."
sqlite3 /config/data/jellyfin.db "PRAGMA journal_mode=WAL;"
echo "Verifying WAL mode..."
sqlite3 /config/data/jellyfin.db "PRAGMA journal_mode;"
echo "Done!"
volumeMounts:
- name: jellyfin-data
mountPath: /config
volumes:
- name: jellyfin-data
persistentVolumeClaim:
claimName: jellyfin-config
Benefits:
- Multiple readers can access database during writes
- Reduces lock contention significantly
- Better performance under concurrent load
- Industry standard for high-concurrency SQLite
Caveats:
- Creates additional files (
jellyfin.db-wal,jellyfin.db-shm) - Requires slightly more disk space
- NFS must support file locking (appears to work based on current setup)
Option B: Adjust Task Scheduling
Prevent database optimization and library scans from running simultaneously.
Current Schedule:
- Library scan: Every 12 hours (04:26, 16:26)
- Database optimization: Every 6 hours (04:27, 10:28, 16:29)
Recommended Change: Modify Jellyfin's scheduled tasks via the web UI:
- Go to Dashboard → Scheduled Tasks
- Change "Optimize database" to run at different times:
- Change from every 6 hours to daily at 03:00 (before library scan)
- This ensures optimization completes before library scan starts
Benefits:
- Simple configuration change
- No code modifications needed
- Reduces overlap probability
Caveats:
- Doesn't eliminate all race conditions
- API requests during optimization can still fail
- Less robust than WAL mode
Option C: Increase SQLite Timeout
Configure Jellyfin to wait longer when database is locked.
Implementation: Requires adding environment variable to Jellyfin deployment:
env:
- name: SQLITE_BUSY_TIMEOUT
value: "30000" # 30 seconds
Note: This may not be supported by Jellyfin directly. WAL mode is preferred.
Priority 2: Fix Audio Normalization
Diagnosis Steps:
- Check FFmpeg capabilities:
kubectl exec -n media deployment/jellyfin -- ffmpeg -filters 2>&1 | grep -E "(loudnorm|ebur128)"
- Test LUFS detection manually:
kubectl exec -n media deployment/jellyfin -- ffmpeg -i /music/sample.mp3 -af loudnorm=print_format=json -f null - 2>&1
Expected output should include:
{
"input_i": "-23.0",
"input_tp": "-5.0",
"input_lra": "7.0",
"input_thresh": "-33.5",
"target_offset": "0.0"
}
Solution Options:
If filters are missing:
- Jellyfin's FFmpeg build may lack audio normalization filters
- Solution: Disable audio normalization task in Jellyfin (Dashboard → Scheduled Tasks)
If filters exist but fail:
- Some audio files may have incompatible formats
- Solution: Check task logs for specific files causing issues
To disable audio normalization:
- Go to Dashboard → Scheduled Tasks
- Find "Audio Normalization"
- Click on it and disable the task
- This is acceptable - normalization is optional for most users
Priority 3: Clean Up Library Warnings
Option A: Remove Empty Library Folders
If you don't use ebooks or playlists:
- Go to Dashboard → Libraries
- Remove the "ebooks" library if it exists
- The playlists folder is auto-created and can be ignored
Option B: Create the Folders
If you plan to use these features:
kubectl exec -n media deployment/jellyfin -- mkdir -p /ebooks
kubectl exec -n media deployment/jellyfin -- mkdir -p /config/data/playlists
Implementation Plan
Step 1: Enable WAL Mode (RECOMMENDED)
This will resolve the critical database locking issues.
# Apply the WAL enable job
kubectl apply -f jellyfin-wal-enable.yaml
# Wait for completion
kubectl wait --for=condition=complete --timeout=300s job/jellyfin-enable-wal -n media
# Check logs
kubectl logs -n media job/jellyfin-enable-wal
# Restart Jellyfin to ensure WAL mode is active
kubectl rollout restart deployment/jellyfin -n media
Step 2: Disable Audio Normalization (OPTIONAL)
Via Jellyfin Web UI:
- Navigate to https://jellyfin.caffeinetux.com/web/index.html#!/scheduledtasks.html
- Find "Audio Normalization"
- Click "Disable"
Step 3: Monitor Logs
After implementing WAL mode:
# Watch for database lock errors (should disappear)
kubectl logs -n media deployment/jellyfin -f | grep "database is locked"
# Check if WAL mode is active
kubectl exec -n media deployment/jellyfin -- sqlite3 /config/data/jellyfin.db "PRAGMA journal_mode;"
# Should output: wal
Performance Impact Analysis
Current Issues:
- Database locks during library scans (2+ minutes)
- Failed API requests during optimization
- Metadata updates delayed or skipped
After WAL Mode:
- ✅ Concurrent reads during writes
- ✅ API requests succeed during optimization
- ✅ Faster metadata updates
- ✅ Better overall responsiveness
Trade-offs:
- Slightly more disk space (typically <10% of DB size)
- Additional files in config directory
- Minimal performance overhead (usually net positive)
Additional Recommendations
1. Database Optimization Frequency
Current: Every 6 hours may be excessive
Recommendation: Change to once daily at 03:00
Benefits:
- Reduces I/O load on NFS
- Less frequent database locks
- Sufficient for most libraries
2. Library Scan Optimization
Current behavior:
- Full library scan every 12 hours
- Stops directory watching during scan
Recommendation:
- Keep 12-hour schedule for now
- Monitor scan duration (currently 2-5 minutes)
- If scans take too long, consider:
- Increasing interval to 24 hours
- Using real-time monitoring only
3. NFS Considerations
Your Jellyfin database is on NFS. WAL mode works with NFS if:
- ✅ File locking is supported (appears to be working)
- ✅ NFS client supports mmap operations
- ⚠️ Network latency is low (check if you experience slowness)
If WAL mode causes issues on NFS:
- Switch back to DELETE mode:
PRAGMA journal_mode=DELETE; - Consider moving database to local storage (emptyDir volume)
- Keep media on NFS, database local
Monitoring and Validation
Success Criteria:
After implementing WAL mode, verify:
- No more database lock errors:
kubectl logs -n media deployment/jellyfin --since=24h | grep "database is locked"
# Should return no results
- WAL mode is active:
kubectl exec -n media deployment/jellyfin -- sqlite3 /config/data/jellyfin.db "PRAGMA journal_mode;"
# Should output: wal
- Library scans complete successfully:
kubectl logs -n media deployment/jellyfin | grep "Scan Media Library Completed"
# Should show successful completions
- Database optimization runs without conflicts:
kubectl logs -n media deployment/jellyfin | grep "jellyfin.db optimized successfully"
# Should show successful optimizations
Summary
Critical Issues (Fix Now):
- SQLite Database Locking → Enable WAL mode
Optional Improvements:
- Audio Normalization → Disable if not needed
- Library Warnings → Remove unused libraries or create folders
- Task Scheduling → Adjust optimization frequency to daily
Expected Outcome:
- Elimination of database lock errors
- Smoother library scans
- Better API responsiveness
- Cleaner logs
Resources
Analysis Date: 2025-11-22 Jellyfin Namespace: media Database Location: /config/data/jellyfin.db (NFS-backed PVC)