Skip to content

[Bug]: Built-in Steam client renders blank window on Unraid/NVIDIA; Flatpak Steam works as workaround #240

Description

@coast2toast

Describe the Bug

After updating to the latest Unraid / current Steam-Headless image, the container starts and the desktop is reachable through noVNC, but the built-in Steam client renders as a blank/empty window.

This does not appear to be a general Xorg, NVIDIA, Docker runtime, or VNC/noVNC issue:

  • NVIDIA runtime works inside containers.
  • Xorg starts successfully with the NVIDIA driver.
  • noVNC/x11vnc works.
  • XFCE desktop renders.
  • xterm, xclock, and xeyes all render normally inside the Steam-Headless desktop.
  • Steam process starts.
  • steamwebhelper starts.
  • Steam detects the RTX 3080 correctly.
  • Only the built-in Steam client / Steam WebHelper UI renders blank.

The working workaround was to install and run Flatpak Steam stable as the default user, disable the built-in Steam autostart, and autostart Flatpak Steam instead.

Working Solution / Workaround

The fix was to bypass the built-in Steam client and use Flatpak Steam stable inside the same working Debian Steam-Headless container.

Install Flatpak Steam as the default user:

docker exec -it steam-headless bash -lc '
runuser -u default -- bash -lc "
export HOME=/home/default
export XDG_RUNTIME_DIR=/run/user/99
export XDG_DATA_DIRS=/var/lib/flatpak/exports/share:/usr/local/share:/usr/share

flatpak --user remote-add --if-not-exists flathub https://flathub.org/repo/flathub.flatpakrepo
flatpak --user install -y flathub com.valvesoftware.Steam//stable
flatpak --user override --filesystem=/mnt/games com.valvesoftware.Steam
"
'

Run Flatpak Steam explicitly as the stable branch:

docker exec -it steam-headless bash -lc '
runuser -u default -- bash -lc "
export HOME=/home/default
export USER=default
export LOGNAME=default
export DISPLAY=:55
export XDG_RUNTIME_DIR=/run/user/99
export XDG_DATA_DIRS=/home/default/.local/share/flatpak/exports/share:/var/lib/flatpak/exports/share:/usr/local/share:/usr/share
export LANG=en_US.UTF-8
export LC_ALL=en_US.UTF-8
export GTK_A11Y=none

dbus-run-session -- flatpak run --user com.valvesoftware.Steam//stable
"
'

This renders correctly.

Important: running without the explicit //stable branch caused Flatpak to try the wrong ref in this environment:

error: app/com.valvesoftware.Steam/x86_64/master not installed

So the working run command must be:

flatpak run --user com.valvesoftware.Steam//stable

not just:

flatpak run com.valvesoftware.Steam

Permanent Workaround

Disable the built-in Steam autostart and create a Flatpak Steam autostart entry.

Example:

docker exec -it steam-headless bash -lc '
pkill -u default -f steam || true

mkdir -p /home/default/.config/autostart-disabled
mv /home/default/.config/autostart/steam.desktop /home/default/.config/autostart-disabled/steam.desktop 2>/dev/null || true

mkdir -p /home/default/.config/autostart

cat > /home/default/.config/autostart/steam-flatpak.desktop <<'"'"'EOF'"'"'
[Desktop Entry]
Type=Application
Name=Steam Flatpak
Exec=sh -lc "export HOME=/home/default; export USER=default; export LOGNAME=default; export DISPLAY=:55; export XDG_RUNTIME_DIR=/run/user/99; export XDG_DATA_DIRS=/home/default/.local/share/flatpak/exports/share:/var/lib/flatpak/exports/share:/usr/local/share:/usr/share; export LANG=en_US.UTF-8; export LC_ALL=en_US.UTF-8; export GTK_A11Y=none; dbus-run-session -- flatpak run --user com.valvesoftware.Steam//stable"
Hidden=false
NoDisplay=false
X-GNOME-Autostart-enabled=true
EOF

chown -R default:users /home/default/.config
'

Proposed Code Fix

I think the container should support an official Flatpak Steam mode, since the image already configures Flatpak and Flatpak Steam works around this built-in Steam/WebHelper rendering issue.

Suggested new environment variable

STEAM_INSTALL_METHOD=native

Supported values:

native
flatpak

Default remains native to preserve current behavior.

When set to:

STEAM_INSTALL_METHOD=flatpak

the container should:

  1. Install Flathub for the container user.
  2. Install com.valvesoftware.Steam//stable as the container user.
  3. Apply a filesystem override for /mnt/games.
  4. Generate an autostart entry that launches Flatpak Steam instead of /usr/games/steam.
  5. Explicitly launch the stable ref.
  6. Set the required runtime environment variables.

Example implementation logic

In the Steam configuration script, roughly:

if [ "${STEAM_INSTALL_METHOD:-native}" = "flatpak" ]; then
    runuser -u "${USER}" -- bash -lc "
        export HOME=/home/${USER}
        export XDG_RUNTIME_DIR=/run/user/$(id -u ${USER})
        export XDG_DATA_DIRS=/home/${USER}/.local/share/flatpak/exports/share:/var/lib/flatpak/exports/share:/usr/local/share:/usr/share

        flatpak --user remote-add --if-not-exists flathub https://flathub.org/repo/flathub.flatpakrepo
        flatpak --user install -y flathub com.valvesoftware.Steam//stable
        flatpak --user override --filesystem=/mnt/games com.valvesoftware.Steam
    "

    cat > "/home/${USER}/.config/autostart/steam-flatpak.desktop" <<EOF
[Desktop Entry]
Type=Application
Name=Steam Flatpak
Exec=/usr/local/bin/start-flatpak-steam.sh
Hidden=false
NoDisplay=false
X-GNOME-Autostart-enabled=true
EOF

    chown -R "${USER}:${USER}" "/home/${USER}/.config/autostart"
fi

Add a wrapper script like:

#!/usr/bin/env bash
set -e

export HOME="${HOME:-/home/default}"
export USER="${USER:-default}"
export LOGNAME="${LOGNAME:-default}"
export DISPLAY="${DISPLAY:-:55}"
export XDG_RUNTIME_DIR="${XDG_RUNTIME_DIR:-/run/user/99}"
export XDG_DATA_DIRS="${HOME}/.local/share/flatpak/exports/share:/var/lib/flatpak/exports/share:/usr/local/share:/usr/share"
export LANG="${LANG:-en_US.UTF-8}"
export LC_ALL="${LC_ALL:-en_US.UTF-8}"
export GTK_A11Y=none

mkdir -p "${XDG_RUNTIME_DIR}"
chmod 700 "${XDG_RUNTIME_DIR}" || true

exec dbus-run-session -- flatpak run --user com.valvesoftware.Steam//stable

Suggested validation/fail-fast checks

Because Flatpak/bubblewrap needs container permissions that may not be obvious, the container should warn if /dev/fuse is missing:

if [ ! -e /dev/fuse ]; then
    echo "WARNING: Flatpak Steam mode requires /dev/fuse. Add --device=/dev/fuse to the container."
fi

Recommended Docker params for Flatpak mode:

--device=/dev/fuse
--cap-add=SYS_ADMIN
--security-opt seccomp=unconfined

The current recommended Steam-Headless NVIDIA parameters can remain:

--runtime=nvidia
--shm-size=8G
--ipc=host
--ulimit nofile=131072:524288
--ulimit memlock=-1:-1
--device=/dev/uinput
--device-cgroup-rule='c 13:* rmw'
--cap-add=NET_ADMIN
--cap-add=SYS_NICE

Summary

The core issue appears to be the built-in Debian Steam client / Steam WebHelper rendering blank in this container environment. The container desktop, Xorg, NVIDIA runtime, and VNC are working.

Flatpak Steam stable works in the same container/session when launched as the default user with the correct environment and explicit //stable ref.

A first-class STEAM_INSTALL_METHOD=flatpak option would provide a clean workaround for users affected by this built-in Steam/WebHelper rendering regression.

Steps to Reproduce

  1. Start josh5/steam-headless:latest / Debian image on Unraid with NVIDIA runtime.
  2. Use RTX 3080 with NVIDIA passthrough.
  3. Open the noVNC web UI.
  4. Launch the built-in Steam client.
  5. Steam process and Steam WebHelper start, but the Steam window is blank.
  6. Launch test X apps:
docker exec -it steam-headless bash -lc '
su - default -c "DISPLAY=:55 xterm &" || true
su - default -c "DISPLAY=:55 xclock &" || true
su - default -c "DISPLAY=:55 xeyes &" || true
DISPLAY=:55 xrefresh || true
'
  1. xterm, xclock, and xeyes render correctly, confirming this is not a general VNC/Xorg paint issue.

Expected Behavior

Expected Behavior

The built-in Steam client should render its login/library UI normally inside the Steam-Headless VNC desktop.

Actual Behavior

The built-in Steam client launches, creates Steam / steamwebhelper windows, but the window contents remain blank.

Steam appears to start successfully enough to spawn the runtime and webhelper processes, but the UI does not paint.

Screenshots

No response

Relevant Settings

Container Extra Parameters used during testing:

--runtime=nvidia \
--shm-size=8G \
--ipc=host \
--ulimit nofile=131072:524288 \
--ulimit memlock=-1:-1 \
--cap-add=NET_ADMIN \
--cap-add=SYS_ADMIN \
--cap-add=SYS_NICE \
--security-opt seccomp=unconfined \
--device=/dev/fuse \
--device=/dev/uinput \
--device-cgroup-rule='c 13:* rmw'

Important paths:

/home/default -> direct BTRFS pool path, not /mnt/user/shfs
/mnt/games    -> direct game library path
DISPLAY       -> :55
PUID/GID      -> default user uid=99, gid=100

Confirmed /home/default was not on Unraid shfs:

Filesystem     Type   Size  Used Avail Use% Mounted on
/dev/sdg1      btrfs  913G  160G  733G  18% /home/default

TARGET        SOURCE                             FSTYPE OPTIONS
/home/default /dev/sdg1[/appdata/steam-headless] btrfs rw,noatime,ssd,discard=async,space_cache=v2,subvolid=5,subvol=/

Host/container memory settings confirmed:

vm.max_map_count = 1048576
vm.overcommit_memory = 0 initially; also tested with overcommit_memory=1
/dev/shm = 32G
ulimit -v = unlimited
ulimit -l = unlimited
Container ShmSize = 8589934592
IpcMode = host

Version

Build: [2026-06-27 03:45:44] [master] [096fc4b] [debian]

Platform

Host:

Unraid: latest/current 7.x branch
Kernel: 6.18.33-Unraid
GPU: NVIDIA GeForce RTX 3080
GPU UUID: GPU-09837522-12b1-ea2f-f0b6-7a45912ebabe
GPU architecture: Ampere / GA102
Docker runtime: NVIDIA runtime working
Container image tested: josh5/steam-headless:latest / debian
Display: :55

NVIDIA driver versions tested:

610.43.02
595.84
595.80 open-source
580.159.04

All driver versions showed the same blank Steam UI behavior.

Relevant log output

Things Tried That Did Not Fix It

NVIDIA runtime validation

NVIDIA runtime works in a test CUDA container:

docker run --rm --runtime=nvidia \
  -e NVIDIA_VISIBLE_DEVICES=all \
  -e NVIDIA_DRIVER_CAPABILITIES=all \
  nvidia/cuda:12.6.2-base-ubuntu22.04 nvidia-smi

Result: RTX 3080 is detected successfully.

Xorg validation

Xorg starts successfully and loads the NVIDIA driver:

xorg RUNNING
NVIDIA GPU NVIDIA GeForce RTX 3080
Virtual screen size configured to be 1600 x 900
Setting mode "NULL"

Supervisor Steam start

supervisorctl start steam reports a spawn/backoff condition:

steam: ERROR (spawn error)
steam BACKOFF Exited too quickly

However, this appears misleading because launching Steam manually does start Steam processes and WebHelper processes.

Manual built-in Steam launch

Tested:

docker exec -it steam-headless bash -lc '
su - default -c "DISPLAY=:55 GTK_A11Y=none HOME=/home/default /usr/games/steam"
'

Also tested with CEF flags:

/usr/games/steam -cef-disable-gpu -cef-disable-gpu-compositing -no-cef-sandbox

Steam starts, but the UI remains blank.

Steam cache resets

Tried clearing/moving:

/home/default/.steam/steam/config/htmlcache
/home/default/.steam/steam/config/cefdata
/home/default/.steam/steam/appcache/httpcache
/home/default/.cache/mesa_shader_cache
/home/default/.cache/nvidia

No change.

XFCE compositor

Disabled compositor:

docker exec -it steam-headless bash -lc '
su - default -c "DISPLAY=:55 xfconf-query -c xfwm4 -p /general/use_compositing -s false" || true
'

No change.

sysctl tuning

Tested:

sysctl -w vm.max_map_count=1048576
sysctl -w vm.max_map_count=2147483642
sysctl -w vm.overcommit_memory=1

No change.

NVIDIA driver rollback/branch testing

Tested all available Unraid NVIDIA plugin driver options:

610.43.02
595.84
595.80 open-source
580.159.04

All behaved the same. Built-in Steam remained blank.

Arch image test

Also tested josh5/steam-headless:arch, but that image did not reach a working Xorg session.

Relevant Arch log:

Configure X11 with GPU ID: 'NVML library version: 610.43'
spawnerr: can't find command '/usr/libexec/accounts-daemon'
spawnerr: can't find command 'tcpserver'
xorg exited status 1
xorg entered FATAL state

The Arch image appears to be a separate issue. The generated GPU ID is invalid; it seems to be parsing NVML library version: 610.43 instead of a GPU UUID or PCI BusID.

Relevant Built-in Steam Logs

Built-in Steam successfully detects the GPU:

Running query: 1 - GpuTopology
Response: gpu_topology {
  gpus {
    id: 1
    name: "NVIDIA GeForce RTX 3080"
    vram_size_bytes: 10995367936
    driver_id: k_EGpuDriverId_NvidiaProprietary
    driver_version_major: 610
    driver_version_minor: 43
    driver_version_patch: 2
  }
  default_gpu_id: 1
}
Exit code: 0

Steam Runtime Launch Service starts:

Steam Runtime Launch Service: starting steam-runtime-launcher-service
Steam Runtime Launch Service: steam-runtime-launcher-service is running
bus_name=com.steampowered.PressureVessel.LaunchAlongsideSteam

But Steam/WebHelper still renders blank.

One repeated warning/error pattern seen with the built-in Steam client:

mmap() failed: Cannot allocate memory
mmap() failed: Cannot allocate memory
mmap() failed: Cannot allocate memory

This persisted even after increasing vm.max_map_count, increasing shm, using ipc=host, and setting unlimited memlock.

Metadata

Metadata

Assignees

No one assigned

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions