Repository navigation
Portal capture hangs on live client connection after loading restore token (succeeds during self-test) — GNOME headless Remote Login session #5750
Description
Is there an existing issue for this?
- I have searched the existing issues
Is your issue described in the documentation?
- I have read the documentation
Is your issue present in the latest beta/pre-release?
None
Describe the Bug
Description
Portal-based screen capture (capture = portal) succeeds completely and consistently during Sunshine's own internal startup self-test — including full hardware encoder validation against the GPU — but deterministically hangs on the first live client connection from a Moonlight client, at the exact same point every time, regardless of encoder setting, portal daemon state, or restore token freshness. The Moonlight client eventually times out (Error 4).
Environment specifics: this occurs specifically when the GNOME session is a headless one created via GDM's "Remote Login" feature (RDP connecting to the GDM greeter and starting a fresh session, rather than sharing an already-active local session). The session has no physical display attached; Sunshine correctly finds and streams the session's virtual Mutter output (Meta-0) during self-test.
Steps to reproduce:
Start a GNOME session via GDM Remote Login (RDP) on a machine with no physical display active
Launch sunshine from a terminal inside that session, or from a program shortcut, with capture = portal and encoder = vulkan explicitly set in sunshine.conf
Observe Sunshine's own startup self-test succeed fully (see log below — finds the Meta-0 stream, validates h264_vulkan/hevc_vulkan/av1_vulkan against the GPU, reaches "Starting main loop")
From a separate device, connect via Moonlight and attempt to launch any application (including the default Desktop entry)
Observe the log stop advancing immediately after [portalgrab] Loaded portal restore token from disk, with no further output, until the client times out.
Things ruled out during troubleshooting, each independently tested:
Firewall/network configuration (the hang occurs before any RTSP/streaming port would be involved — this is local capture negotiation only)
Stale restore token (reproduced immediately after a fresh interactive portal approval — see "Saved portal restore token to disk" in the log, ~63 seconds before self-test, following a manual xdg-desktop-portal/xdg-desktop-portal-gnome restart)
Encoder auto-detection churn (reproduced with encoder pinned explicitly to vulkan, eliminating the nvenc/vaapi/software cascade entirely — only one self-test cycle runs, and it succeeds)
KMS-specific capability issues (not applicable — capture is explicitly portal, not kms & KMS streaming session was succesful when I had the host PC turned on and logged in, prior to switching to portal capture and virtual display session)
Expected Behavior
A live Moonlight connection should be able to start a stream using the same portal capture path that Sunshine's own self-test just used successfully seconds earlier.
Additional Context
This report was put together with AI assistance, Claude helped me troubleshoot the issue and draft this report. The theory is a hypothesis, not 100% confirmed obviously, however; this matches a known general class of bug in async XDG-portal D-Bus clients, where a portal call is made before the response-signal listener is subscribed, and a fast response (as happens when reusing an already-approved restore token) can fire and be missed before the subscriber registers, causing an indefinite wait. That pattern would explain why an isolated self-test (minimal concurrent activity) consistently succeeds while a live client session (RTSP server and connection handling running concurrently) consistently loses that race, but neither of us has inspected Sunshine's actual portal-client source to confirm this is the real mechanism, so please treat it as a lead rather than a diagnosis.
Host Operating System
Linux
Operating System Version
OS: Arch Linux x86_64 // Kernel: Linux 7.2.6-arch2-1
Architecture
amd64/x86_64
Package
Linux - LizardByte/pacman-repo
GPU Type
AMD
GPU Model
Asus TUF 7900 XTX
GPU Driver/Mesa Version
mesa 1:26.2.3-1
Capture Method
XDG Portal Grab (FreeBSD/Linux)
Apps
All apps - main test is launching steamLog output
[2026-09-18 23:32:59.577]: Info: Sunshine version: 2026.914.233613 commit: 63d35f702ee9e362e43263742981836ec0710384
[2026-09-18 23:32:59.577]: Info: Package Publisher: LizardByte
[2026-09-18 23:32:59.577]: Info: config: 'capture' = portal
[2026-09-18 23:32:59.577]: Info: config: 'encoder' = vulkan
[2026-09-18 23:34:02.751]: Info: [portalgrab] Saved portal restore token to disk
[2026-09-18 23:34:02.751]: Info: [wayland] Found display [wayland-0]
[2026-09-18 23:34:02.752]: Info: [wayland] Name: Meta-0
[2026-09-18 23:34:02.752]: Info: [wayland] Found monitor: MetaVendor
[2026-09-18 23:34:02.753]: Info: [portalgrab] Found stream for display id/name: 'Meta-0' position: 0x0 resolution: 1920x1080
[2026-09-18 23:34:02.769]: Info: Trying encoder [vulkan]
[2026-09-18 23:34:02.805]: Info: Creating encoder [h264_vulkan]
[2026-09-18 23:34:02.823]: Info: Vulkan encode using GPU: AMD Radeon RX 7900 XTX (RADV NAVI31)
[2026-09-18 23:34:02.970]: Info: Creating encoder [hevc_vulkan]
[2026-09-18 23:34:02.989]: Info: Vulkan encode using GPU: AMD Radeon RX 7900 XTX (RADV NAVI31)
[2026-09-18 23:34:03.091]: Info: Creating encoder [av1_vulkan]
[2026-09-18 23:34:03.107]: Info: Vulkan encode using GPU: AMD Radeon RX 7900 XTX (RADV NAVI31)
[2026-09-18 23:34:03.147]: Info: Found H.264 encoder: h264_vulkan [vulkan]
[2026-09-18 23:34:03.147]: Info: Found HEVC encoder: hevc_vulkan [vulkan]
[2026-09-18 23:34:03.147]: Info: Found AV1 encoder: av1_vulkan [vulkan]
[2026-09-18 23:34:03.148]: Error: Failed to create client: Daemon not running
[2026-09-18 23:34:03.149]: Info: Configuration UI available at [https://localhost:47990]
[2026-09-18 23:34:03.182]: Warning: Failed to create system tray
[2026-09-18 23:34:03.182]: Info: Starting main loop
[2026-09-18 23:34:03.182]: Info: Main loop has exited
--- Live Moonlight connection attempt, ~54 seconds later ---
[2026-09-18 23:34:57.533]: Info: Display device configuration is disabled. Reverting any active display device configuration.
[2026-09-18 23:34:57.536]: Info: Trying encoder [vulkan]
[2026-09-18 23:34:57.536]: Error: Failed to gain CAP_SYS_ADMIN
[2026-09-18 23:34:57.536]: Info: [misc] drop_elevated_privileges succeeded in dropping capabilities
[2026-09-18 23:34:57.536]: Info: Screencasting with XDG portal
[2026-09-18 23:34:57.536]: Info: [pipewire] Requested variable frame rate (Sunshine pacing required: 16.6667ms)
[2026-09-18 23:34:57.536]: Info: [wayland] Found display [wayland-0]
[2026-09-18 23:34:57.543]: Info: [portalgrab] Loaded portal restore token from disk
--- log stops here; no further output; client times out (Error 4) ---Online logs
No response
Activity
NovaStorm775 commentedon Sep 19, 2026
Sorry just posting on my lunch break at work, happy to provide more info if needed!
Raw Log Output:
psyke83 commentedon Sep 23, 2026
I tested GDM Remote Login using this procedure with GNOME 51 (with #5774).
Setup:
Before testing Sunshine, I tested RDP login on its own to see how the feature works. It seems that on RDP connect, a new virtual monitor is created that displays the GDM login screen which can load a desktop session. However, the crucial detail that impacts Sunshine is that once you disconnect from the RDP session, the entire virtual session is closed.
To verify, I tested the following:
My conclusion is that GDM Remote Login can't realistically work with Sunshine unless the remote login session can be configured to remain persistent after the RDP connection is closed. If The virtual monitor can be set up normally and GDM configured to autologin to it, it could work, otherwise it doesn't seem suitable.
psyke83 commentedon Sep 23, 2026
As an alternative, I was able to use a virtual monitor that fully works with Portal via the following steps:
With all the above done, Portal connect works fine and persist across reboots. Unlike the GDM Remote Login, the cursor is rendered correctly.
NovaStorm775 commentedon Sep 27, 2026
Hi dude, thanks for testing that and confirming that method for me! I've had an attempt at recreating your success and so far no matter the situation I haven't been able to get past the portal load token hang which occurred in my report. I'll keep testing with the next update to sunshine and let you know if anything changes, thanks!
chadwjames commentedon Oct 12, 2026
Seeing the same symptom on a different setup, plus one data point that may help narrow it down.
Symptom: startup self-test passes with portal capture, but on the first live Moonlight launch the log stops right after
[portalgrab] Loaded portal restore token from disk. NoCreateSessionis ever logged, the client never connects, and Moonlight then reports the host as offline (the HTTPS port stops being serviced until Sunshine is restarted).Setup: Bazzite (Fedora Atomic 44) with GNOME Shell 50.5 on Wayland, NVIDIA RTX 3070 (open kernel module 615.71.09, matching Flatpak GL extension), a normal local GNOME session (not GDM Remote Login), Sunshine Flatpak
2026.914.233613from Flathub,encoder = nvenc.What isolated it: on this session the system tray never initializes (
Failed to create system tray→System tray is not initialized→Main loop has exited). Settingsystem_tray = disabledinsunshine.conffixed the launch hang on the same build with no other change: same version, same token, same GNOME session, only that setting differs. Logs below (debug level, redacted).I also tried the pre-release
v2026.1011.160319(which includes #5774). On this session it exits cleanly at startup when the tray fails to initialize, so it needssystem_tray = disabledas well. With that set, launching worked there too. (With the tray enabled it exits before it can be tested, so I can't say whether the pre-release changes the hang on its own.)Possibly worth checking whether the reporter's session also logs a tray failure at startup, and whether
system_tray = disabledchanges the behavior.Stalled: tray enabled (log ends at the token load)
Works: same build,
system_tray = disabled(first part of the launch)NovaStorm775 commentedon Oct 16, 2026
That was a massive help! I have disabled system tray in the config as you suggested, and going forwards, assume it is disabled. Now it launches but the video stream is corrupt.
If I run Sunshine from my physical desktop and then connect to it through Moonlight from my phone or laptop (launching steam big picture as my test), I get Audio through the client device, however the image looks like this (not static, it is dynamic but it is corrupted / broken).

Then, then when I tested the second use case which is: connecting from the client, to my desktop through the remote login session (no physical display), launching sunshine and then switching to Moonlight on the client device, This resulted in a similar problem, Audio carried through but I was stuck with a green screen with no image rendering at all.
One issue is, it seems to be selecting the wrong GPU within my system. I have a DGPU and an IGPU whereas it is selecting the IGPU for the remote login render path. Is it possible to force it to use my 7900 XTX?
Log formatted for clarity: