Bug Symptoms
When a virtual display is used, video capture does not start until the display helper validation gate times out. The gate fires Display helper validation failed; starting capture anyway consistently ~11.0 seconds after APPLY dispatch result=true, and capture only begins after that point.
Moonlight UWP on Xbox Series S times out after roughly 10 seconds, so the client disconnects a fraction of a second before the first frame is produced. On the client this looks like a grey screen followed by a silent disconnect — no error is shown.
Occasionally the first stream after a service start succeeds. This is not a configuration difference: when the client's RTSP handshake completes late enough relative to display creation, the remaining wait falls just under the client timeout. It is a race that is lost almost every time.
Measurements — time from Display helper: APPLY dispatch result=true to Display helper validation failed:
| Run |
VDD |
APPLY confirmed |
Validation failed |
Delta |
Outcome |
| 11:37 |
Sunshine VDD |
23.990 |
34.994 |
11.004 s |
success (57 s session) |
| 11:38 |
Sunshine VDD |
35.701 |
46.710 |
11.009 s |
frame produced, client already gone |
| 11:38 |
Sunshine VDD |
55.558 |
06.548 |
10.990 s |
fail |
| 11:47 |
SudoVDA |
58.030 |
09.033 |
11.003 s |
fail |
The delta is constant to within ~20 ms across runs and across two different virtual display drivers, which suggests a fixed timeout rather than a variable wait on Windows.
Both VDD drivers are affected. With dd_use_sunshine_virtual_display_driver = enabled, Windows never exposes a target-specific display identity:
Sunshine temporary display created before Windows exposed a target-specific display identity; waiting for virtual display enumeration.
Warning: Virtual display scale: monitor device path was unavailable; Windows scale was not applied.
Info: Virtual display created (device name pending enumeration).
With dd_use_sunshine_virtual_display_driver = false (SudoVDA fallback), enumeration is clean:
11:47:57.085 Virtual display scale: requested 250%, recommended 150%, previous 150%, current 250%.
11:47:57.094 Virtual display created at \\.\DISPLAY32
Device name available immediately, scale applied, no warning — and the gate still times out at 11.003 s. This suggests the gate is not actually waiting on display identity resolution, or is waiting on something that never resolves on this system regardless of enumeration state.
Failing run, annotated:
11:38:34.214 Virtual display created (device name pending enumeration).
11:38:35.701 Display helper: APPLY dispatch result=true
11:38:37.195 CLIENT CONNECTED
11:38:37.212 Display helper: waiting for apply/validation gate before starting capture.
... ~9.5 s of nothing ...
11:38:46.710 Error: Display helper validation failed; starting capture anyway.
11:38:47.231 Capture format [DXGI_FORMAT_R16G16B16A16_FLOAT]
11:38:53.851 CLIENT DISCONNECTED
Steps to reproduce
- Fresh install, default settings, pair an Xbox Series S running the official Moonlight app.
- Start a stream. It may succeed once.
- Start another stream. Grey screen, then silent disconnect after ~10 s.
Reproduced after a complete uninstall including deletion of C:\Program Files\Apollo\config, removal of all hidden monitor devices in Device Manager, and a reboot. Default settings, no per-client overrides, single virtual display in vibeshine_state (remembered virtual display device ... (1 total)).
Workaround
Setting virtual_display_mode = disabled and streaming to a hardware dummy plug (EDID matching the client resolution) removes the gate entirely. Capture starts within ~250 ms of CLIENT CONNECTED and sessions run for 10+ minutes without issue. This confirms the gate is the blocking factor, but it requires extra hardware and frame pacing is noticeably worse than with the virtual display.
### Expected Behavior
Capture should start early enough for the client to receive its first frame within Moonlight's connection timeout (~10 s).
The fallback path already does the right thing: after the gate expires it logs `starting capture anyway` and capture works correctly. Possible fixes:
- Don't gate capture start on helper verification — start capture immediately and let verification run in parallel.
- Reduce the gate timeout to well below typical client timeouts.
- Make the gate timeout configurable.
Windows Version
25H2
Package
Windows - exe installer
GPU Type
NVIDIA
GPU Model
NVIDIA GeForce RTX 4070Ti
GPU Driver Version
610.62
Capture Method
Windows.Graphics.Capture (Windows)
Apps
Logs (Optional but Recommended)
vibepollo-log-1133-sunshine-vdd.txt
vibepollo-log-1147-sudovda.txt
Screenshot (Optional)
Bug Symptoms
When a virtual display is used, video capture does not start until the display helper validation gate times out. The gate fires
Display helper validation failed; starting capture anywayconsistently ~11.0 seconds afterAPPLY dispatch result=true, and capture only begins after that point.Moonlight UWP on Xbox Series S times out after roughly 10 seconds, so the client disconnects a fraction of a second before the first frame is produced. On the client this looks like a grey screen followed by a silent disconnect — no error is shown.
Occasionally the first stream after a service start succeeds. This is not a configuration difference: when the client's RTSP handshake completes late enough relative to display creation, the remaining wait falls just under the client timeout. It is a race that is lost almost every time.
Measurements — time from
Display helper: APPLY dispatch result=truetoDisplay helper validation failed:The delta is constant to within ~20 ms across runs and across two different virtual display drivers, which suggests a fixed timeout rather than a variable wait on Windows.
Both VDD drivers are affected. With
dd_use_sunshine_virtual_display_driver = enabled, Windows never exposes a target-specific display identity:With
dd_use_sunshine_virtual_display_driver = false(SudoVDA fallback), enumeration is clean:Device name available immediately, scale applied, no warning — and the gate still times out at 11.003 s. This suggests the gate is not actually waiting on display identity resolution, or is waiting on something that never resolves on this system regardless of enumeration state.
Failing run, annotated:
Steps to reproduce
Reproduced after a complete uninstall including deletion of
C:\Program Files\Apollo\config, removal of all hidden monitor devices in Device Manager, and a reboot. Default settings, no per-client overrides, single virtual display invibeshine_state(remembered virtual display device ... (1 total)).Workaround
Setting
virtual_display_mode = disabledand streaming to a hardware dummy plug (EDID matching the client resolution) removes the gate entirely. Capture starts within ~250 ms ofCLIENT CONNECTEDand sessions run for 10+ minutes without issue. This confirms the gate is the blocking factor, but it requires extra hardware and frame pacing is noticeably worse than with the virtual display.Windows Version
25H2
Package
Windows - exe installer
GPU Type
NVIDIA
GPU Model
NVIDIA GeForce RTX 4070Ti
GPU Driver Version
610.62
Capture Method
Windows.Graphics.Capture (Windows)
Apps
Logs (Optional but Recommended)
vibepollo-log-1133-sunshine-vdd.txt
vibepollo-log-1147-sudovda.txt
Screenshot (Optional)