Troubleshooting
Diagnose permissions, path mappings, parsing, and service failures.
Permissions
The most common category of issue. Your media stack typically runs several applications as different users:
| Application | Typical user | What it does |
|---|---|---|
| SABnzbd/qBittorrent | sabnzbd/qbittorrent | Downloads files |
| Sonarr | sonarr | Manages TV shows |
| Radarr | radarr | Manages movies |
| Plex2Jellyfin daemon | root (bare metal) / PUID:PGID (Docker) | Organizes files into the library |
| Jellyfin/Plex | jellyfin/plex | Serves media |
plex2jellyfin CLI | your user | Manages duplicates, consolidation |
If files are owned by the wrong user or have restrictive permissions, some of these can't read, write, or delete them.
Running in Docker? See Docker → PUID/PGID and file ownership first — most container permission issues are a PUID/PGID mismatch, and the [permissions] config below has no effect in-container.
"Permission denied" running the CLI
Symptom: plex2jellyfin duplicates execute (or consolidate execute) fails with permission errors.
Cause: files or directories don't allow your user to write/delete.
Fix:
- Check your group membership:
groups $USER - Make sure your user is in whatever group owns the library files (a shared
mediagroup is a common pattern) - Directory mode matters as much as file mode — deleting a file requires write permission on its parent directory, not just the file itself. A
dir_modeof0755blocks group deletes;0775allows them.
Files created with the wrong ownership (bare metal)
Symptom: new files land owned by the wrong user.
Cause: the daemon isn't running as root, or [permissions] is misconfigured.
Fix:
- Verify the daemon runs as root:
ps aux | grep plex2jellyfin-daemon - Check the systemd unit:
systemctl cat plex2jellyfin-daemon | grep User - Confirm
[permissions]inconfig.toml— see Configuration →[permissions]
Files created with the wrong ownership (Docker)
[permissions] has no effect in Docker — see why. Set PUID/PGID to match the UID/GID that should own the files instead, and confirm the mapping with docker exec plex2jellyfin id.
Jellyfin can't see new files
Symptom: files appear in the library folder on disk but Jellyfin doesn't show them.
Cause: the Jellyfin process's user can't read the files, or Jellyfin hasn't rescanned.
Fix:
- Check permissions:
ls -la /path/to/library/ - Confirm the Jellyfin user/PUID can read those files (same group, or matching PUID/PGID in Docker)
- Trigger a library rescan in Jellyfin
Fixing existing files (bare metal)
sudo chown -R root:media /path/to/library/
sudo find /path/to/library -type f -exec chmod 664 {} \;
sudo find /path/to/library -type d -exec chmod 775 {} \;Adjust the owner/group and modes to whatever [permissions] you've configured.
Jellyfin path mappings and parse decisions marked FAIL
Symptom: organized files exist and look correct, but decisions never get a jellyfin_item_id, PASS/DRIFT/FAIL labels never appear, or rows eventually show FAIL.
Cause: the post-organize feedback loop (plugin webhook + path translator + sweeper) can't correlate a Jellyfin library item's path with the daemon's path for that file. Typical case: Jellyfin sees /movies1/... while the daemon organized to /mnt/STORAGE1/MOVIES/....
Fix: add [[jellyfin.path_mappings]] covering every root where the two views diverge, and keep the companion plugin installed. See Path mappings and Configuration → Jellyfin path mappings. Re-test Jellyfin in a setup wizard until unmapped roots are empty.
AI audit issues
AI never ran on a file that looked wrong
Symptom: a polluted or odd title landed in the library, but no AI enhancement ran.
Cause: the daemon only queues AI when parse confidence is below auto_trigger_threshold (default 0.6). Movies/episodes with a deterministic identity (title + year or SxxExx, and a non-obfuscated filename) bypass AI even when confidence is low — see shouldQueueForAI in the daemon handler. High-confidence regex parses also skip AI.
Fix: raise naming quality via parser fixes / re-organize, or lower auto_trigger_threshold only if you accept more AI calls. audit --generate still uses confidence_threshold for bulk review.
AI proposes the wrong show or movie
Symptom: audit --generate suggests a title that has nothing to do with the actual file (e.g. suggests "History's Greatest Mysteries" for a Prison Break episode).
Cause: insufficient context reached the model, or folder naming is too obfuscated for even the folder-path hint to help.
Fix:
- Set
DEBUG_AI=1in the daemon/CLI environment and re-run to see exactly what context (library type, folder path, current parse) was sent in the prompt. - Verify the file sits under a sensibly named folder — the AI uses the parent directory name as a hint when the filename itself is ambiguous.
- Raise
confidence_thresholdin[ai](see Configuration) so borderline suggestions get rejected instead of applied.
AI suggests the wrong media type (movie vs. TV)
Fix:
- Confirm the file sits under the correct library root (
[watch]/[libraries]inconfig.toml) — the AI is told which library type it's working in and trusts that. - Re-run
plex2jellyfin scanafter fixing the config so the database reflects the corrected library assignment.
AI calls failing or timing out
Symptom: audit --generate errors out or silently skips files.
Fix:
- Confirm Ollama is reachable at
ollama_endpoint(curl http://localhost:11434/api/tagsor your cloud endpoint). - Check
timeout_secondsisn't too low for your model/hardware. - Check
hourly_limit/daily_limithaven't been hit — the tool self-throttles to protect the endpoint. - If the primary
modelis failing repeatedly, the circuit breaker should fall through tofallback_modelautomatically; confirm both are valid, pulled model names.
Daemon and services
Daemon won't start
systemctl status plex2jellyfin-daemon
journalctl -u plex2jellyfin-daemon -n 100Common causes: config.toml missing or invalid (plex2jellyfin config test), a watch/library path in the config that doesn't exist or isn't readable by root, or the control socket path already in use by a stale process.
Web UI can't reach the daemon
plex2jellyfin-web requires plex2jellyfin-daemon to already be running — the systemd unit declares Wants=/After= on the daemon, but if the daemon crashed after startup, restart both:
sudo systemctl restart plex2jellyfin-daemon plex2jellyfin-webThey communicate only over a Unix-domain control socket, so a firewall or network issue can't be the cause — check that the socket file exists and is owned/readable by both processes' users.
Config changes not taking effect
config.toml isn't hot-reloaded by default. After editing it:
plex2jellyfin daemon reload # picks up config without dropping in-flight watches
# or
sudo systemctl restart plex2jellyfin-daemonDatabase
Corrupted or inconsistent database
plex2jellyfin database path # confirm which file you're looking at
plex2jellyfin database cleanup-housekeeping # collapse duplicate housekeeping failures
plex2jellyfin database reset # nuclear option: delete and reinitializedatabase reset deletes all indexed state (not your media files) — you'll need to plex2jellyfin scan again afterward.
Duplicate series rows / files landing under "Season Unknown"
plex2jellyfin repair series-dedupe
plex2jellyfin repair unknown-seasonsTargeted repair commands for these specific, known failure modes — see CLI Reference → repair.
Still stuck?
Run a postmortem bundle and review the evidence yourself, or hand it to an LLM:
plex2jellyfin postmortem collect --since 96hSee Daemon & Services → Postmortem timer and the CLI Reference.