My Jellyfin config has some YAML like this.
# Sometimes work
devices:
- /dev/dri/renderD128:/dev/dri/renderD128
- /dev/dri/card0:/dev/dri/card0
Occasionally when I reboot my server, I end up with no card0 and instead I have /dev/dri/card1. This breaks my Jellyfin server…
I noticed there is also dri/by-path, which I’m guessing is a more stable path than a card index… however, doing this doesn’t work for me.
# No work
devices:
- /dev/dri/by-path/pci-0000:00:02.0-render:/dev/dri/renderD128
- /dev/dri/by-path/pci-0000:00:02.0-card:/dev/dri/card0
I tried with and without quotes and the result is the same. Error to start. I’m guessing Docker is failing to correctly parse the string because of the colons in pci-0000:00:02.0-card…
How’s everyone else handling this problem? I’ve been updating my compose.yaml every time the index switches, card0 to card1 to card0… but this is getting annoying now. (This is a worse problem now that I’m running Fedora IoT!)
Any thoughts?
If you download hevc main 10 level 5.1 content or below you probably won’t need to transcode and can skip the whole problem 🧠
Just mount
/dev/dri.The by-path approach is the right idea — the issue is that Docker’s
--devicesyntax splits on:, so the colons insidepci-0000:00:02.0-cardconfuse the parser (container_path gets mangled). Two things to try:-
Re-check the exact by-path filenames. They must match what’s actually in
/dev/dri/by-path/on your host — e.g. on Intel iGPU it’s usuallypci-0000:00:02.0-cardandpci-0000:00:02.0-render, but on some boards the PCI address differs. Runls -l /dev/dri/by-path/and confirm the symlink targets exist. -
Drop card entirely — you likely only need the render node. Modern VAAPI/QSV transcoding in Jellyfin works fine with just the render device, no
card0needed:
devices: - /dev/dri/by-path/pci-0000:00:02.0-render:/dev/dri/renderD128This is also the most robust fix for your reboot problem: the render node via by-path doesn’t shuffle between reboots, so your compose file stops breaking.
If you do still want card0 (some older setups use it), a workaround is a udev rule that creates a stable symlink, or a small systemd unit that remaps device access at boot — but for Jellyfin, render-only is the common answer.
-
The colons in the by-path filename are not actually the problem – Docker device strings split on the first colon, so a host path containing colons works fine. The usual failure is that the by-path symlinks are not what you expect: for iGPU rendering there is often only a
-rendersymlink and no-cardone, and the card device may enumerate under a different PCI address than 00:02.0 depending on platform.Check what actually exists:
ls -l /dev/dri/by-path/If there is no
-cardentry for your GPU, that is why the second line fails. On many headless boxes you do not need card0 at all for VAAPI/QSV transcoding – renderD128 is the render node and is what Jellyfin actually uses. Try mounting only the render node:devices: - /dev/dri/by-path/pci-0000:00:02.0-render:/dev/dri/renderD128If your Jellyfin build still insists on a card node, the robust fix is a udev rule or rc.local that symlinks a stable name like
/dev/dri/card-stableto whichever cardN the iGPU landed on, matched by PCI ID via/sys/class/drm/card*/device/uevent. Reference the stable symlink in compose and it survives both reindexing and Fedora IoT imageless updates.The colons in the by-path filename are not actually the problem – Docker device strings split on the first colon, so a host path containing colons works fine. The usual failure is that the by-path symlinks are not what you expect: for iGPU rendering there is often only a
-rendersymlink and no-cardone, and the card device may enumerate under a different PCI address than 00:02.0 depending on platform.Check what actually exists:
ls -l /dev/dri/by-path/If there is no
-cardentry for your GPU, that is why the second line fails. On many headless boxes you do not need card0 at all for VAAPI/QSV transcoding – renderD128 is the render node and is what Jellyfin actually uses. Try mounting only the render node:devices: - /dev/dri/by-path/pci-0000:00:02.0-render:/dev/dri/renderD128If your Jellyfin build still insists on a card node, the robust fix is a udev rule or rc.local that symlinks a stable name like
/dev/dri/card-stableto whichever cardN the iGPU landed on, matched by PCI ID via/sys/class/drm/card*/device/uevent. Reference the stable symlink in compose and it survives both reindexing and Fedora IoT imageless updates.


