# Troubleshooting Sunshine Crashes Diagnostic workflow for when Sunshine is offline, won't start, or crashes. ## Quick debug sequence ```bash # 1. Is it running? systemctl --user status sunshine --no-pager # 2. Any recent crashes in systemd journal? journalctl --user -u sunshine --no-pager -n 50 # 3. Check Sunshine's own log (⚠ overwritten on restart — copy first!) cat ~/.config/sunshine/sunshine.log | grep -i "fatal\|error\|hang\|terminate" # 4. Stale processes? ps aux | grep -i sunshine | grep -v grep # 5. Port conflicts? ss -tlnp | grep -E "47984|47989|47990|48010" # 6. Restart systemctl --user restart sunshine ``` ## Common crash patterns ### "Hang detected! Session failed to terminate in 10 seconds" **Symptom:** Sunshine dies after a Moonlight client connects or disconnects. Log shows: ``` Fatal: Hang detected! Session failed to terminate in 10 seconds. ``` **Cause:** NVENC encoder or X11 capture pipeline hung during session teardown. The internal 10-second watchdog fires and kills the process. **Common root cause — missing window manager:** Sunshine's X11 capture requires a running window manager or desktop environment on DISPLAY=:0. An X server alone (login screen, headless with no WM) allows capture to start but teardown of the X11 pipeline hangs without a WM managing the window resources. This produces a reproducible Hang detected crash every time a Moonlight client attempts a session. **Diagnostic — check WM before restarting:** ```bash # Is a window manager running on :0? ps aux | grep -iE "openbox|xfce|gnome|kde|mutter|xfwm" | grep -v grep # Is X11 alive? DISPLAY=:0 xdpyinfo 2>&1 | head -5 # If X11 is running but no WM, start one: DISPLAY=:0 openbox --replace & # Then restart Sunshine systemctl --user restart sunshine ``` **Fix:** If a WM is running, restart Sunshine — this may be a transient encoder hang. If it happens repeatedly and a WM is present: - Check for GPU driver instability (`nvidia-smi` for errors) - Stop co-resident LLM models to free VRAM before gaming (`ollama stop`) - Consider increasing session timeout (Sunshine Web UI → Configuration → General) - If on a headless server, ensure the dummy plug hasn't become unseated — no connected display causes similar hang behavior ### Silent death (log just stops, no error) **Symptom:** Sunshine.log has startup messages then just ends. No Fatal, no Error, no "Terminate handler called." **Possible causes:** - OOM kill (check `dmesg | grep -i "out of memory"`) - SIGKILL from systemd (check `journalctl --user -u sunshine` for signal) - Second "Hang detected" crash where the log was overwritten before the Fatal line was flushed to disk **Fix:** Restart and watch live: `tail -f ~/.config/sunshine/sunshine.log` in another terminal, then connect a Moonlight client and disconnect. Observe the teardown sequence. ### "Couldn't bind RTSP server to port [48010], Address already in use" **Symptom:** Logged as `Fatal` during startup but Sunshine continues running. **Cause:** A stale Flatpak wrapper process from a previous crash still holds port 48010. **Impact:** Moonlight uses RTSP (port 48010) for streaming protocol negotiation. Without it, clients get "RTSP handshake failed" (error 10060/connection timeout) even though Sunshine appears running and the HTTPS ports (47984, 47989) and Web UI (47990) are up. **Fix:** ```bash # Find and kill the stale wrapper (not the new /usr/bin/sunshine) ps aux | grep sunshine | grep -v grep kill # Then restart so Sunshine rebinds all ports cleanly systemctl --user restart sunshine # Verify all four ports are listening ss -tlnp | grep -E "47984|47989|47990|48010" ``` ### Clean SIGTERM ("Terminate handler called") **Symptom:** Log shows `Info: Terminate handler called` with no preceding error. **Cause:** Something sent SIGTERM — manual stop (`systemctl --user stop`), systemd cleanup, or a Hermes agent session issuing restart. **Fix:** Just restart. Not a crash — check system journal around the timestamp for what sent the signal. ### RTSP connection reset / "No pending session" (error 10054) **Symptom:** Moonlight client reports "Starting RTSP handshake failed: error 10054" (Windows) or "Connection reset by peer." Sunshine log shows: ``` Debug: No pending session for incoming RTSP connection ``` Sunshine is running, all ports are listening (verified with `ss -tlnp | grep sunshine`), and HTTPS/HTTP serverinfo requests succeed — but every RTSP connection is immediately reset. **Cause:** The Moonlight client was never paired, or its pairing was lost. Sunshine's RTSP server requires a pending session created by the HTTP pairing flow BEFORE accepting RTSP connections. With zero paired clients, there is never a pending session, so every RTSP connection gets RST immediately. **Diagnostic — check pairing state:** ```bash python3 -c " import json with open('$HOME/.config/sunshine/sunshine_state.json') as f: state = json.load(f) paired = state.get('paired_clients', []) print(f'Paired clients: {len(paired)}') " ``` If the count is 0, the client must be paired. **Fix — pair the client:** 1. Open Moonlight, click "+", enter `192.168.50.98` (or let it auto-discover) 2. Moonlight prompts for a PIN 3. Open Sunshine Web UI at `https://:47990/pin` 4. Enter the PIN shown in Moonlight into the Web UI 5. After pairing, RTSP connections will be accepted **Troubleshooting IP Mismatch during pairing:** If the Web UI says "Success!" but Moonlight still says "PC Offline" and `sunshine_state.json` still shows 0 paired clients, this is an **IP routing mismatch**. Sunshine drops the pairing if the client IP Moonlight is using (e.g., Tailscale `100.x.x.x`) doesn't match the IP you used in the browser to access the Web UI (e.g., LAN `192.168.x.x`). **Fix:** Make sure the IP address typed into Moonlight's "Add PC" dialog *exactly matches* the IP address in your browser's address bar when entering the PIN. **Note on `origin_pin_allowed`:** With `origin_pin_allowed = pc` in sunshine.conf, only localhost connections auto-pair. All LAN/WAN clients must enter a PIN. If `origin_pin_allowed = lan`, Tailscale clients get "Request Timed out" during pairing because Sunshine rejects the non-LAN source address. **Error code reference:** | Error | Meaning | Likely cause | |---|---|---| | 10060 | Connection timeout | Port not listening, firewall, Sunshine not running, stale process holding port 48010, OR **Sunshine crashed instantly upon connection (check log for audio `pa_simple_new` errors)** | | 10054 | Connection reset by peer | RTSP server rejecting — unpaired client, or RTSP server module broken | ### Instant Crash on Connection (Audio Init Failure) **Symptom:** Moonlight connects successfully via HTTP, logs show `New streaming session started`, but Sunshine crashes immediately. Moonlight reports `Error 10060` (Timeout / PC Offline) because the server died before the RTSP streaming ports could be reached. **Log shows:** ``` Error: pa_simple_new() failed: Invalid argument Error: Unable to initialize audio capture. The stream will not have audio. ``` **Cause:** In Sunshine v2026+, hardcoded `audio_sink = auto_null` or `virtual_sink = auto_null` in `sunshine.conf` causes a fatal crash during PulseAudio/PipeWire initialization when the client attempts to start the stream. **Fix:** Remove `audio_sink` and `virtual_sink` from `~/.config/sunshine/sunshine.conf` and restart Sunshine. Allow Sunshine to auto-detect the PipeWire virtual sinks. ## Log locations | Source | Path | Persistence | |---|---|---| | Sunshine app log | `~/.config/sunshine/sunshine.log` | **Overwritten on restart** — copy before restarting | | Systemd journal (user) | `journalctl --user -u sunshine` | Persistent across restarts | | System journal | `journalctl --since "HH:MM" --until "HH:MM"` | Persistent, broader system context | | Sunshine state | `~/.config/sunshine/sunshine_state.json` | Persists across restarts (client pairings, app list) | ## Preserving crash logs Sunshine.log is the most useful for debugging but is wiped on restart. Always copy first: ```bash cp ~/.config/sunshine/sunshine.log ~/sunshine-crash-$(date +%Y%m%d-%H%M).log ``` Then restart and compare the old crash log against the new startup log.