Troubleshooting
This page covers the fastest recovery steps for the public Polaris host flow. Use the web UI’s Troubleshooting screen first when it is still reachable.
Web UI credentials
Section titled “Web UI credentials”Reset the web UI username and password:
polaris --creds new-username new-passwordRun this as the same user account that runs Polaris. Do not use sudo unless Polaris itself runs
as root, because that can update a different config directory.
Restart Polaris after changing credentials. A running Polaris process keeps the previous credentials in memory until restart.
For packaged user-service installs:
systemctl --user restart polarisFor foreground sessions, stop Polaris and start it again.
Web UI does not load
Section titled “Web UI does not load”- Confirm Polaris is running.
- Check that you are opening
https://localhost:47990orhttps://localhost:<port + 1>if you changedport. - Accept the local HTTPS certificate warning in the browser.
- Check your local firewall rules if the UI is unreachable from another device on the LAN.
Polaris and Sunshine on the same host
Section titled “Polaris and Sunshine on the same host”Polaris keeps its config under ~/.config/polaris, so installing it should not remove or overwrite
an existing Sunshine setup. Do not run both hosts on the default GameStream/Moonlight ports at the
same time unless you intentionally change one host’s port value.
For a quick Polaris test, stop Sunshine first:
systemctl --user stop sunshinesystemctl --user enable --now polarisIf Sunshine runs as a system service on your distro, use the matching system-service command instead. To switch back, stop Polaris and start Sunshine again.
Headless session does not start cleanly
Section titled “Headless session does not start cleanly”Confirm these settings first:
headless_mode = enabledlinux_use_cage_compositor = enabledlinux_prefer_gpu_native_capture = enabledThat is the intended Headless Stream path for NVIDIA/NVENC and AMD/Mesa VAAPI hosts that can keep
frames GPU-resident. It avoids touching your normal desktop layout and reduces display mode churn
after a session ends. If the stream is stable but logs report SHM/RAM capture, treat that as a
performance/capability fallback first, not a startup failure. If enabling GPU-native capture blocks
launch on a specific driver/compositor stack, temporarily set it to disabled and include the
capture decision fields in the bug report.
The built-in Desktop entry does not launch your existing KDE, GNOME, or wlroots desktop inside this private compositor. If the client connects but shows an empty or black desktop while app entries work, that usually means the headless runtime is alive but nothing visible has been launched in it. Use Desktop Display mode when you want to stream the already-running host desktop session.
Steam Big Picture black screen or tiny window
Section titled “Steam Big Picture black screen or tiny window”Clear Steam’s HTML cache:
rm -rf ~/.local/share/Steam/config/htmlcache/If you are using MangoHud, disable it for Steam Big Picture and Steam/Proton launches first. Those paths are the most sensitive to early helper-process crashes.
Input does not work
Section titled “Input does not work”The udev rules and modules-load configuration ship as package files, so virtual input works after the next reboot with nothing else to run. To use it without rebooting first, load the modules once:
sudo modprobe uinput uhidIf the problem persists, ensure your user has access to the input stack expected by your distro setup:
sudo usermod -aG input "$USER"Then sign out and back in.
On an ostree host — Bazzite, Bluefin, Silverblue and relatives — that command does nothing
useful: the input group lives in /usr/lib/group rather than /etc/group, so usermod
finds no group to add anyone to. Universal Blue images ship a recipe that copies the
definition across first:
ujust add-user-to-input-groupPolaris detects this and prints whichever command applies to your host.
If Polaris was installed before the rules became package files, an older copy may still sit in
/etc/udev/rules.d/60-polaris.rules. /etc overrides the packaged file, so that copy keeps
shadowing later fixes — including the seat isolation rules, which then never apply no matter what
the configuration says.
sudo -H polaris --setup-hostHost setup removes that copy only when its contents still match the file this Polaris ships. An older version’s copy does not match — that is what upgrading changed — so it is kept, with a warning naming the file, because nothing can tell it apart from a copy you edited yourself. Upgrading is therefore the case most likely to leave a shadowing file behind.
If you did not edit it, remove it and reload:
sudo rm /etc/udev/rules.d/60-polaris.rulessudo udevadm control --reload-rulesThen confirm the packaged rules are the ones in effect:
grep -c seat-isolated /usr/lib/udev/rules.d/60-polaris.rulesClient input also types into the host desktop
Section titled “Client input also types into the host desktop”A private stream session and the desktop session logged in at the machine both see the virtual
keyboard and mouse Polaris creates, so a client’s typing reaches both. Enable
client_keyboard_mouse_seat_isolation to assign those devices to a dedicated seat, or ignore them
by name in your desktop compositor. See
host and private session input isolation.
Local desktop audio is captured during a headless stream
Section titled “Local desktop audio is captured during a headless stream”In headless labwc sessions, Polaris routes launched apps to the Polaris virtual sink and captures
that sink directly instead of changing the user’s global default audio output. The healthy log path
looks like:
Linux audio isolation: routing launched apps to virtual sink [sink-sunshine-stereo] without changing the user's default sinkLinux audio isolation: capturing virtual sink without changing the user's default sinkIf local Plasma/GNOME audio is still mixed into the stream, include the audio section of the logs and whether the client requested host audio. Host-audio mode intentionally captures the host sink, so same-user local apps can still be part of that stream.
Thread priority warning during a stream
Section titled “Thread priority warning during a stream”If the log shows this warning during an otherwise working stream:
Thread priority elevation unavailable; continuing with the default schedulerPolaris is running, but the user service cannot raise capture, encode, or audio worker priority.
Packaged installs include LimitRTPRIO=95 and LimitNICE=-10 in polaris.service; reload the user
manager and restart Polaris after updating the package:
systemctl --user daemon-reloadsystemctl --user restart polarisIf the warning remains, the user manager inherited stricter limits from the login session. Confirm the active unit with:
systemctl --user cat polarisjournalctl --user -u polaris -b --no-pager | grep -E 'Thread priority|RealtimeKit|SCHED_FIFO'Installing and running RealtimeKit can also allow priority elevation without granting broad capabilities to the Polaris binary.
Packaged Linux user units are ordered with graphical-session.target and pass through common
desktop environment variables such as WAYLAND_DISPLAY, XDG_RUNTIME_DIR, and
DBUS_SESSION_BUS_ADDRESS. In private Headless Stream mode, a missing parent WAYLAND_DISPLAY
is logged as a limited desktop-preview/portal warning instead of a stream startup failure because
Polaris starts its own labwc Wayland socket for the client session.
NVIDIA KMS capture issues
Section titled “NVIDIA KMS capture issues”If KMS capture gives a black screen on NVIDIA, confirm the kernel is using:
nvidia_drm.modeset=1If you do not need DRM/KMS capture, keep using the default compositor and portal paths instead.
A startup warning that says KMS probe could not access DRM framebuffer handles; continuing with non-KMS capture backends when available is informational for portal/compositor users; do not apply
setcap unless you intentionally selected KMS capture.
If a manually copied explicit-KMS test binary still logs Failed to gain CAP_SYS_ADMIN after
setcap, check the mount options for the binary path. File capabilities are ignored on nosuid
mounts, so /tmp builds can be misleading; copy the test binary to a normal path such as
/usr/local/bin before applying setcap.
For low-FPS NVIDIA headless reports, check Build features: cuda=... first. If the log says
cuda=disabled and later shows Attempting to use NVENC without CUDA support. Reverting back to GPU -> RAM -> GPU, the stream is taking an extra CPU copy/upload path. Use a CUDA-enabled package
or rebuild with -DPOLARIS_ENABLE_CUDA=ON before comparing headless performance against Sunshine.
The expected fast-path markers for NVIDIA true-headless testing look like this:
Build features: cuda=enabledlabwc: Starting in headless modewlr: Using ext-image-copy-capture DMA-BUF for headless labwccapture_transport=dmabuf frame_residency=gputarget_device=cuda target_residency=gpudisplay_preview: Failed to capture cage screenshot is the web dashboard preview path, not the
stream capture path. Repeated failures are rate-limited in the log, and the dashboard backs off
preview refreshes after failed captures. If the preview is missing, confirm grim is installed with
command -v grim.
For capture performance, check /polaris/v1/session/status; its capture object includes
path, reason, reason_message, cpu_copy, gpu_native, and nested decision fields.
/polaris/v1/stream-policy exposes the same data as capture_path, capture_path_reason,
capture_path_reason_message, capture_cpu_copy, capture_gpu_native, and capture_decision.
A reason such as headless_shm_fallback means Headless Stream is healthy enough to run but still
using the conservative SHM/system-memory path. headless_extcopy_dmabuf is the true-headless
DMA-BUF path, and gpu_native_requested_shm_fallback means GPU-native capture was requested but
the Wayland capture path still fell back to SHM. Support bundles include the same normalized
decision data under capture.decision and stream stats capture_decision so a report captures
the selected path, reason message, transport, residency, runtime backend, effective headless
state, and GPU-native override state.
For LTS distro expectations and package caveats, see the Linux LTS Headless Fallback Matrix. Xvfb or gamescope should be treated as investigation-only unless this supported labwc path cannot cover a confirmed target environment.
VAAPI or software encode fallback
Section titled “VAAPI or software encode fallback”If Polaris cannot hold the preferred hardware path, open Mission Control or Troubleshooting and check the active runtime path. Polaris surfaces when capture or encode falls back so you do not need to guess from a black-box client session.
Linux HDR or Main10 has wrong colors
Section titled “Linux HDR or Main10 has wrong colors”If the log says stream_hdr_enabled=false, treat that stream as SDR. A client HDR request or
hdr_mode = 2 can still move the encoder into a 10-bit/P010 path, but it does not make a non-HDR
Linux capture path into a true HDR source. On AMD VAAPI systems, keep hdr_mode = 0 and disable
client HDR requests until SDR colors are correct, then test HEVC Main 8-bit before testing Main10.
For true HDR, look for all of these lines in the same launch:
HDR metadata: available=true usable=trueColor coding: HDR (Rec. 2020 + SMPTE 2084 PQ)HDR decision: ... display_hdr=true hdr_metadata_available=true stream_hdr_enabled=trueIf stream_hdr_enabled=false, Polaris is being conservative: the client may have requested HDR or Main10,
but the active Linux display path did not provide enough metadata to advertise a real HDR stream.
If usable=false, the display path exposed an HDR metadata blob, but Polaris rejected it because core
static metadata such as display primaries or max display luminance was missing.
Support bundle and logs
Section titled “Support bundle and logs”When reporting a bug:
- Export the support bundle from the Troubleshooting screen.
- Include the active route, capture backend, encoder, and client device.
- Mention whether the session was headless, host-display, or virtual-display.
If the UI is unavailable, the main host config lives in ~/.config/polaris and the service logs
can be captured with your systemd user journal.
Reporting a crash
Section titled “Reporting a crash”Released builds are stripped, so a backtrace needs the matching debug package. On Arch:
sudo pacman -S polaris-debugcoredumpctl info polariscoredumpctl prints a symbolised backtrace for the most recent crash. Include it verbatim, along
with the Polaris log lines from the same session — the shutdown line names what asked Polaris to
stop, which distinguishes a crash from an ordinary exit.