Hardware transcode: [InitHWSupport] Supported HW codecs [0] gives no actionable reason when VAAPI actually works
Have you enabled troubleshooting mode?
- I confirm that the troubleshooting mode is enabled.
Describe the bug
DISCLAIMER: I have done my troubleshooting with Opus 4.8 (Max thinking), solved it, now reporting back about the case. So yes, this report was written with the help of AI.
On a system where hardware VAAPI encode is fully functional, stash's startup probe still logs:
[InitHWSupport] Supported HW codecs [0]:
and every transcode falls back to libx264, with no indication in the UI or at the default (Info/Warning) log level as to why. The per-codec failure reason is only emitted at Debug (pkg/ffmpeg/codec_hardware.go, the logger.Debugf("[InitHWSupport] Codec %s not supported...") branch).
Verifying the hardware is genuinely fine - all of these succeed as the stash user:
vainfo --display drm --device /dev/dri/renderD128 → iHD, H.264/HEVC VAEntrypointEncSlice
stash's exact detection command, reconstructed from the source (-qp 20, format=nv12,hwupload,scale_vaapi=…), exits 0
Yet stash reports [0]. Enabling Debug revealed the real, hidden error:
[AVHWDeviceContext] No VA display found for device /dev/dri/renderD128.
Device creation failed: -22.
Failed to set value '/dev/dri/renderD128' for option 'vaapi_device': Invalid argumentRoot cause in our case was a too-narrow systemd sandbox rule — DeviceAllow=/dev/dri rw under DevicePolicy=closed. libva needs the whole DRM device class; DeviceAllow=char-drm rw fixes it (SR-IOV VFs expose multiple /dev/dri nodes — card* + renderD* — and a single path grant isn't enough).
The problem this issue is about is not that environment quirk itself, but that stash surfaced nothing to diagnose it — [0] at Info with the cause buried at Debug meant the only path to the answer was reading codec_hardware.go and reproducing the probe by hand.
Steps to reproduce
device-cgroup scope, independent of stash
# FAILS — "No VA display found", despite the device working unrestricted
systemd-run --pipe -p User=stash -p DevicePolicy=closed -p DeviceAllow="/dev/dri rw" \
ffmpeg -hide_banner -vaapi_device /dev/dri/renderD128 -f lavfi \
-i color=c=red:s=640x480 -t 0.1 -c:v h264_vaapi -qp 20 \
-vf "format=nv12,hwupload" -f null -
# SUCCEEDS — only the device rule changed
systemd-run --pipe -p User=stash -p DevicePolicy=closed -p DeviceAllow="char-drm rw" \
ffmpeg -hide_banner -vaapi_device /dev/dri/renderD128 -f lavfi \
-i color=c=red:s=640x480 -t 0.1 -c:v h264_vaapi -qp 20 \
-vf "format=nv12,hwupload" -f null -Expected behaviour
Surface the reason. When InitHWSupport finds no codecs, emit the per-codec failure output at Info (or summarise it in the UI / the new Troubleshooting Mode), so [0] is diagnosable without Debug logs and source reading. Even a single line like h264_vaapi unavailable: No VA display found for /dev/dri/renderD128 would have turned a long investigation into a minute.
Docs note. In the hardware-acceleration docs, mention that under systemd device sandboxing VAAPI needs DeviceAllow=char-drm rw (not a single /dev/dri path), particularly for SR-IOV VFs.
Screenshots or additional context
No response
Stash version
v0.31.1
Device details
Debian 13, kernel 6.12.107 Intel iGPU via SR-IOV VF (Raptor Lake-S UHD), iHD driver 25.2.3 Runs as a systemd service, non-root stash user, member of render + video VAAPI H.264/HEVC encode confirmed working outside stash
Relevant log output
Source: stashapp/stash