A film imported by Radarr at 17:08 was still missing from Jellyfin hours later. It was readable, in the right folder, in a format Jellyfin already handled elsewhere in the same library. It had zero rows in Jellyfin's database. Real-time monitoring was enabled the whole time, and could never have worked. This is structural, not a misconfiguration. The same trap catches Plex and Emby on any network share written by a different machine.
Before you blame the watcher, confirm the file is genuinely fine. This takes a minute and saves you chasing permissions:
# readable by the user the media server runs as?
sudo -u jellyfin ls -l "/mnt/movies/Young Guns (1988)/"
# does the library path match what the server has configured?
# and is the format one it already handles?
All three checked out. The library already indexed twelve other .iso files, so full-disc images
were not the issue. The item was never scanned. The last library scan ran at 14:05, the import happened at
17:08, and the next scheduled scan was not until roughly 02:03. It was going to appear eventually. Up to
twelve hours later.
Jellyfin's EnableRealtimeMonitor, "Enable real time monitoring" in Library settings, uses
inotify, the Linux kernel's filesystem notification interface. inotify reports changes the
local kernel observes on a filesystem.
An NFS client's kernel does not observe writes made by a different NFS client. When another machine writes a file to the share, your kernel is not told. Nothing happened locally. There is no event to deliver, so the watcher never fires. It is not slow or unreliable. There is nothing there to see.
The setting still shows as enabled, which is the worst part. It looks like a working mechanism and provides nothing.
This applies to SMB and CIFS too, and to any setup where the *arr stack runs on a different host, in a different VM or container, or on a different VLAN from the media server. If the media server is the machine doing the writing, real-time monitoring works fine. That is why plenty of people never see this.
The normal answer is to have the downloader tell the media server. In Radarr or Sonarr, add a Connect notification under Settings → Connect → Emby/Jellyfin that fires on import and triggers a library scan. If you can do that, do it. It is event-driven and immediate.
It assumes the downloader can reach the media server's API, which is not always true. If your *arr stack lives on an isolated VLAN, a common and sensible arrangement for torrent traffic, the connection you need runs from the isolated network into your LAN. Exactly the direction that isolation exists to prevent. Punching a hole through it so a library can refresh is a poor trade.
Invert it. Instead of the writer notifying the reader, have the reader watch the mount and trigger its own scan. It is already allowed to talk to itself. A systemd timer on the media server host, every few minutes:
#!/usr/bin/env bash
# /usr/local/bin/jellyfin-autoscan.sh
set -euo pipefail
STATE=/var/lib/jellyfin-autoscan/state
mkdir -p "$(dirname "$STATE")"
# Cheap fingerprint of the libraries: newest mtime + entry count.
now=$(find /mnt/movies /mnt/tv -maxdepth 2 -printf '%T@ %p\n' 2>/dev/null \
| sort -rn | head -20 | md5sum | cut -d' ' -f1)
prev=$(cat "$STATE" 2>/dev/null || true)
if [ "$now" != "$prev" ]; then
echo "$now" > "$STATE"
# Debounce: only scan once things have stopped changing.
exit 0
fi
# Unchanged since last run, so the copy finished. Scan if we have not already.
if [ ! -f "$STATE.scanned" ] || [ "$STATE" -nt "$STATE.scanned" ]; then
curl -fsS -X POST "http://127.0.0.1:8096/Library/Refresh" \
-H "X-Emby-Token: $JELLYFIN_API_KEY"
touch "$STATE.scanned"
fi
Two details that matter more than the script:
# /etc/systemd/system/jellyfin-autoscan.timer
[Unit]
Description=Poll media mounts and trigger a Jellyfin library scan
[Timer]
OnBootSec=5min
OnUnitActiveSec=5min
[Install]
WantedBy=timers.target
systemctl enable --now jellyfin-autoscan.timer
systemctl list-timers jellyfin-autoscan.timer