Debug Recipes
Since: 0.18.0
Common debugging scenarios and the commands to diagnose them. Start with tail -f .logs/phlix.log in most cases.
Playback fails / transcoding errors
1. Check the transcode log
Every transcode job writes a log to .logs/transcode/<job-id>.log. Find the job ID from media.log or streaming.log:
# Watch media channel for transcode job IDs
tail -f .logs/media.log | grep -i "transcode\|job"
# Read a specific transcode log
cat .logs/transcode/abc123def.log2. Verify FFmpeg is installed and accessible
ffmpeg -version
ffprobe -versionIf FFmpeg is not found or the version is very old, reinstall:
# Ubuntu/Debian
sudo apt install ffmpeg
# Or use the jellyfin-ffmpeg PPA for a more up-to-date build
sudo add-apt-repository ppa:jonathonf/ffmpeg-4
sudo apt update && sudo apt install ffmpeg3. Check hardware acceleration
# NVIDIA NVENC
ffmpeg -hide_banner -encoders 2>&1 | grep nvenc
# Intel VAAPI
vainfo
# Intel Quick Sync
ffmpeg -hide_banner -encoders 2>&1 | grep qsv
# AMD VAAPI
ffmpeg -hide_banner -encoders 2>&1 | grep vaapiNo output for your expected encoder means hardware acceleration is not active. See /advanced/hardware-transcoding to enable it.
Library scan is slow or hanging
1. Check the media log
tail -f .logs/media.logLook for Scanning entries showing progress and Matched or Unmatched for each file.
2. Force a foreground rescan to see errors
sudo -u phlix php bin/phlix library:scan {libraryId} --rescan 2>&1This runs the scan synchronously in your shell and prints errors that may not appear in the log.
⚠ --rescan also runs the prune, so it is not a read-only diagnostic — it will delete rows whose files are genuinely gone. It is safe after relocating media, though: a top-level item whose file was moved without being renamed is re-pointed at its new path rather than deleted (see Moving a file). A plain library:scan {libraryId} does not prune.
What --rescan buys you depends on the library type. On a music library it makes the scanner refuse every unchanged-file skip, so every track is opened and tag-read — exactly what you want when hunting a file the incremental scan is silently passing over. (The skip index is still loaded; it just cannot suppress a read in this mode — see Rescan loads the index on purpose.) On every other type the flag is inert (those scanners have no skip index), and a path that is already indexed is stepped over either way. On a movie or TV library, the way to make something look at such a row again is match-metadata / refresh-metadata — but note their limits (what they skip, wrong vs missing match). On a photo, book or audiobook library nothing revisits the row at all: those job types skip it, so the only option is to remove the row and let a scan re-add it.
The command exits 0 on a clean scan, 1 if the scan did not run at all, and 3 if it completed but could not index every file it read. It refuses to start (exit 1) while the library already has a queued/running job — pass --force only when you know the existing row is stranded. See the CLI reference.
3. Check file permissions
The phlix system user must be able to read all media directories:
sudo -u phlix php -r "realpath('/mnt/media/movies/');" 2>&1If this returns nothing, the user cannot access the path. Fix with:
sudo chown -R phlix:phlix /mnt/mediaServer won't start
1. Check the Workerman log
cat workerman.log
journalctl -u phlix-server --no-pager -n 502. Check for port conflicts
lsof -i :8096 # HTTP port
lsof -i :8097 # WebSocket portIf another process is using either port, either kill it or change Phlix's bind port in config/server.php.
3. Verify the database can be reached
mysql -u phlix -p -h 127.0.0.1 phlix -e "SELECT 1;"If this fails, MySQL may not be running or credentials may be wrong. Check /etc/phlix/env for DB_* values.
4. Run migrations explicitly
sudo -u phlix php scripts/run-migrations.phpIf migrations fail, restore the database from a backup and retry.
Hub connection fails
1. Check the hub log channel
tail -f .logs/phlix.log | grep -i hub2. Verify the JWKS URL is reachable from the server
curl -s https://hub.phlix.media/.well-known/jwks.json | head -c 200If this fails, the server cannot reach the Hub — check network/firewall rules.
3. Verify the enrollment token is valid
cat /etc/phlix/hub-enrollment.jsonAn expired or missing enrollment token prevents the server from connecting. Re-enroll from the Hub admin UI: Hub Admin → Servers → Re-enroll.
4. Check relay tunnel status
tail -f .logs/phlix.log | grep -i relayIf the relay is repeatedly reconnecting, check config/relay.php — use ws://127.0.0.1:8802 for a co-located Hub or the correct wss:// address for a remote Hub.
High CPU / memory usage
1. Identify the source process
top -c
htop2. Check transcode jobs
ps aux | grep ffmpeg | grep -v grepMany concurrent FFmpeg processes indicate the transcode limit (max_concurrent_transcodes) is not being respected or is set too high.
3. Check for deadlocks
tail -100 .logs/phlix.log | grep -i "deadlock\|timeout\|fatal"The DB connection pool is on by default (DB_POOL_ENABLED defaults to 1 as of Stream Quality/ABR step S9). While diagnosing, either pin DB_POOL_SIZE=1 as a safe, fully-serialised pool size, or set DB_POOL_ENABLED=0 to fall all the way back to the single-connection coroutine mutex path:
DB_POOL_SIZE=1 sudo systemctl restart phlix-server
# or, to bypass the pool entirely:
DB_POOL_ENABLED=0 sudo systemctl restart phlix-serverPlugin installation fails
1. Check the plugins log
tail -f .logs/plugins.log2. Verify the catalog is reachable
curl -s https://github.com/detain/phlix-plugins/contents/plugins.json | head -c 5003. Check PHP composer and network access
Plugins are installed via composer install over HTTPS. If your server is air-gapped, either:
- Set
PHLIX_PLUGINS_ALLOW_HTTP=1and host the plugin on an internal HTTP server, or - Install the plugin manually by placing it in
var/plugins/
4. Verify signature requirements
If PHLIX_PLUGINS_REQUIRE_SIGNATURE=1 is set, the plugin must have a valid signature from a key in the trusted allowlist. Try setting it to 0 temporarily to see if that resolves the installation.
Authentication / login failures
1. Check the AUTH log
tail -f .logs/auth.logThis records every login attempt with the user identifier, success/failure status, and IP address.
2. Verify JWT_SECRET
If tokens are failing immediately after issue, JWT_SECRET may have changed (e.g. an env var that was set for one session is not set for another):
grep JWT_SECRET /etc/phlix/env3. Check the database connection
mysql -u phlix -p -h 127.0.0.1 phlix -e "SELECT id, email FROM users LIMIT 5;"A connection failure here means the auth layer cannot read user credentials.