{"id":680,"date":"2026-04-19T16:10:36","date_gmt":"2026-04-20T00:10:36","guid":{"rendered":"https:\/\/nramkumar.org\/tech\/?p=680"},"modified":"2026-04-19T16:10:36","modified_gmt":"2026-04-20T00:10:36","slug":"plex-hardware-acceleration-in-proxmox-container-update","status":"publish","type":"post","link":"https:\/\/nramkumar.org\/tech\/blog\/2026\/04\/19\/plex-hardware-acceleration-in-proxmox-container-update\/","title":{"rendered":"Plex Hardware Acceleration In Proxmox Container &#8211; Update"},"content":{"rendered":"\n<p class=\"wp-block-paragraph\">I had <a href=\"https:\/\/nramkumar.org\/tech\/blog\/2024\/05\/25\/using-hardware-acceleration-in-a-proxmox-plex-container\/\">posted earlier about enabling hardware acceleration for Plex in a Proxmox container.<\/a> After a bunch of updates of both the proxmox host and the container + Plex, at some point the hardware acceleration stopped working. The issue I saw was the host would log a bunch of errors related to the i915 GPU driver whenever I played something that required transcoding (side note: Transcoding is quite rare for me as most of my devices support direct playback. The scenario that kicks it in is using the web player + turning on subtitles). The errors looked like this and happened when I was trying to play HEVC content with subtitles turned on in the web player:<\/p>\n\n\n\n<pre class=\"wp-block-code\"><code>kernel: traps: Plex Transcoder&#91;1676352] trap divide error ip:7c2adbb2107f sp:7ffd269901f0 error:0 in libavformat.so.60\nkernel: i915 0000:00:02.0: &#91;drm] GPU HANG: ecode 11:4:a8ffff7d, in Plex Transcoder &#91;1676352]\nkernel: i915 0000:00:02.0: &#91;drm] Plex Transcoder&#91;1676352 context reset due to GPU hang\nkernel: i915 0000:00:02.0: &#91;drm] Resetting vcs0 for preemption time out\nkernel: i915 0000:00:02.0: &#91;drm] GPU HANG: ecode 11:4:7f871f6f, in Plex Transcoder &#91;1676352]\nkernel: i915 0000:00:02.0: &#91;drm] Plex Transcoder&#91;1676352 context reset due to GPU hang\nkernel: i915 0000:00:02.0: &#91;drm] Resetting vcs0 for CS error<\/code><\/pre>\n\n\n\n<p class=\"wp-block-paragraph\">For context, my setup is the following:<\/p>\n\n\n\n<ul class=\"wp-block-list\">\n<li>Hardware &#8211; Intel Elkhart Lake iGPU<\/li>\n\n\n\n<li>Host: Proxmox<\/li>\n\n\n\n<li>Plex: Running as unprivileged container, running the latest plex version<\/li>\n\n\n\n<li>Host passes the necessary hardware devices to the container<\/li>\n\n\n\n<li>Container gid mapping is used to allow access to the hardware devices from the container<\/li>\n<\/ul>\n\n\n\n<p class=\"wp-block-paragraph\">I made the following changes to make this scenario work.<\/p>\n\n\n\n<h2 class=\"wp-block-heading\">Host GPU Driver Setup<\/h2>\n\n\n\n<p class=\"wp-block-paragraph\">Create a file \/etc\/modprobe.d\/i915.conf with the following contents:<\/p>\n\n\n\n<pre class=\"wp-block-code\"><code>options i915 enable_guc=3 enable_fbc=0 enable_psr=0<\/code><\/pre>\n\n\n\n<p class=\"wp-block-paragraph\">Now update these settings into the image and reboot:<\/p>\n\n\n\n<pre class=\"wp-block-code\"><code>update-initramfs -u\nreboot<\/code><\/pre>\n\n\n\n<h2 class=\"wp-block-heading\">BIOS Settings<\/h2>\n\n\n\n<p class=\"wp-block-paragraph\">Ensure the hardware is configured to have enough memory to handle 4K streams. I changed the following settings:<\/p>\n\n\n\n<ul class=\"wp-block-list\">\n<li><strong>Internal Graphics:<\/strong> <code>Enabled<\/code><\/li>\n\n\n\n<li><strong>Primary Display:<\/strong> <code>IGFX<\/code><\/li>\n\n\n\n<li><strong>DVMT Pre-Allocated:<\/strong> <code>160M<\/code> (or at least 64M).<\/li>\n\n\n\n<li><strong>DVMT Total Gfx Mem:<\/strong> <code>MAX<\/code>.<\/li>\n\n\n\n<li><strong>Aperture Size:<\/strong> <code>256MB<\/code> or <code>512MB<\/code>.<\/li>\n\n\n\n<li><strong>Protected Audio Video Path: <\/strong>Disabled (Optional &#8211; under headless Linux this is not very useful)<\/li>\n<\/ul>\n\n\n\n<h2 class=\"wp-block-heading\">GPU Passthrough to LXC And Permissions<\/h2>\n\n\n\n<p class=\"wp-block-paragraph\">Previously, I was passing only the render node. For full hardware control, we will need to pass the master node as well. Edit the LXC config in \/etc\/pve\/lxc\/ID.conf to add:<\/p>\n\n\n\n<pre class=\"wp-block-code\"><code>lxc.cgroup2.devices.allow: c 226:0 rwm\nlxc.cgroup2.devices.allow: c 226:128 rwm\nlxc.autodev: 1\nlxc.mount.entry: \/dev\/dri\/card0 dev\/dri\/card0 none bind,optional,create=file\nlxc.mount.entry: \/dev\/dri\/renderD128 dev\/dri\/renderD128 none bind,optional,create=file<\/code><\/pre>\n\n\n\n<h2 class=\"wp-block-heading\">ID Mapping In LXC<\/h2>\n\n\n\n<p class=\"wp-block-paragraph\">In addition to the id mapping of the render group in host and container, we also need to map the id for video group in host and container. The process is similar &#8211; the GID in both host and container for video group is typically 44. Here&#8217;s what the GID mapping looks like in the LXC configuration (\/etc\/pve\/lxc\/ID.conf) &#8211; you will need to adjust this to the actual IDs in your setup:<\/p>\n\n\n\n<pre class=\"wp-block-code\"><code>lxc.idmap: u 0 100000 65536\nlxc.idmap: g 0 100000 44\nlxc.idmap: g 44 44 1\nlxc.idmap: g 45 100045 61\nlxc.idmap: g 106 104 1\nlxc.idmap: g 107 100107 65429<\/code><\/pre>\n\n\n\n<p class=\"wp-block-paragraph\">Remember to allow remapping of host GID 44 in \/etc\/subgid as well.<\/p>\n\n\n\n<h2 class=\"wp-block-heading\">Allowing Hardware Access To The Plex User<\/h2>\n\n\n\n<p class=\"wp-block-paragraph\">Lastly, since the plex process runs as the user plex, it will need to get access to the hardware devices. We do this by adding the plex user to the render and video groups in the container.<\/p>\n\n\n\n<pre class=\"wp-block-code\"><code>sudo usermod -aG render plex\nsudo usermod -aG video plex<\/code><\/pre>\n\n\n\n<p class=\"wp-block-paragraph\">Restarting the container should now allow hardware transcoding in the plex container to work!<\/p>\n\n\n\n<h2 class=\"wp-block-heading\">Debugging<\/h2>\n\n\n\n<p class=\"wp-block-paragraph\">Verify that the Graphics Microcontroller is enabled on the host:<\/p>\n\n\n\n<pre class=\"wp-block-code\"><code>sudo find \/sys\/kernel\/debug\/dri -name \"*guc_info*\"<\/code><\/pre>\n\n\n\n<p class=\"wp-block-paragraph\">Check the resulting file for status of GuC.<\/p>\n\n\n\n<h2 class=\"wp-block-heading\">Why This Works<\/h2>\n\n\n\n<ul class=\"wp-block-list\">\n<li><strong><code>enable_guc=3<\/code><\/strong>: Hands off frame scheduling from the CPU to the GPU&#8217;s internal microcontrollers, eliminating &#8220;heartbeat&#8221; timeouts.<\/li>\n\n\n\n<li><strong><code>enable_fbc=0<\/code><\/strong>: Disables Framebuffer Compression, which is a known trigger for <code>vcs0<\/code> engine resets on Gen11.<\/li>\n\n\n\n<li><strong>DVMT 160M<\/strong>: Ensures the initial buffer mapping for 4K HEVC doesn&#8217;t overflow and crash the driver.<\/li>\n<\/ul>\n\n\n\n<p class=\"wp-block-paragraph\"><\/p>\n","protected":false},"excerpt":{"rendered":"<p>I had posted earlier about enabling hardware acceleration for Plex in a Proxmox container. After a bunch of updates of both the proxmox host and the container + Plex, at some point the hardware acceleration stopped working. The issue I saw was the host would log a bunch of errors related to the i915 GPU&#8230;<\/p>\n","protected":false},"author":1,"featured_media":0,"comment_status":"open","ping_status":"open","sticky":false,"template":"","format":"standard","meta":{"footnotes":""},"categories":[1],"tags":[],"class_list":["post-680","post","type-post","status-publish","format-standard","hentry","category-uncategorized"],"_links":{"self":[{"href":"https:\/\/nramkumar.org\/tech\/wp-json\/wp\/v2\/posts\/680","targetHints":{"allow":["GET"]}}],"collection":[{"href":"https:\/\/nramkumar.org\/tech\/wp-json\/wp\/v2\/posts"}],"about":[{"href":"https:\/\/nramkumar.org\/tech\/wp-json\/wp\/v2\/types\/post"}],"author":[{"embeddable":true,"href":"https:\/\/nramkumar.org\/tech\/wp-json\/wp\/v2\/users\/1"}],"replies":[{"embeddable":true,"href":"https:\/\/nramkumar.org\/tech\/wp-json\/wp\/v2\/comments?post=680"}],"version-history":[{"count":1,"href":"https:\/\/nramkumar.org\/tech\/wp-json\/wp\/v2\/posts\/680\/revisions"}],"predecessor-version":[{"id":681,"href":"https:\/\/nramkumar.org\/tech\/wp-json\/wp\/v2\/posts\/680\/revisions\/681"}],"wp:attachment":[{"href":"https:\/\/nramkumar.org\/tech\/wp-json\/wp\/v2\/media?parent=680"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/nramkumar.org\/tech\/wp-json\/wp\/v2\/categories?post=680"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/nramkumar.org\/tech\/wp-json\/wp\/v2\/tags?post=680"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}