Skip to content

WSASendMsg() failed: 10022 (WSAEINVAL) on every WAN / port-forwarded UDP send — IP_PKTINFO source address rejected. Minimal single-NIC repro, reproduces on both Sunshine and Apollo. #5443

Description

@MathLeee

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?

This issue is present in the latest pre-release

Describe the Bug

Over a port-forwarded WAN connection, every outbound video/ping UDP packet fails with WSASendMsg() failed: 10022 (WSAEINVAL). The stream reaches CLIENT CONNECTED and the encoder is created fine, but not a single UDP packet leaves the host, so the client hits Initial Ping Timeout after ~10s.

LAN streaming is 100% fine — including dialing the host's own public IP and letting it NAT-loopback. Only genuine external clients arriving through the router's port-forward fail. The first 10022 appears ~17ms after the encoder is created, on the initial small ping reply (single packet via send(), no USO cmsg), so this is not USO/offload related.

I reduced it to a minimal repro and it still fails identically on both Sunshine and Apollo (shared Windows send path).

Ruled out with single-variable A/B tests (each with logs):

Hypothesis Test Result
Encoder/GPU ruled out; the YUV444 / NvEncUnregisterAsyncEvent lines are normal encoder-probe noise between the "// Testing for available encoders //" banners; all NVENC encoders create fine
Video encryption wan_encryption_mode=0 still 10022
IPv4-mapped / dual-stack address_family=ipv4 (client logged as bare IPv4, no ::ffff:) still 10022
Multiple NICs / IP forwarding / virtual adapters reduced to a single Ethernet adapter, forwarding disabled still 10022
Routing single default route, in/out interface identical not the cause
Implementation Sunshine -> Apollo identical 10022

Expected Behavior

A client connecting over WAN through a router port-forward should stream normally (outbound UDP packets are sent), exactly as it does on LAN.

Additional Context

Root cause: in src/platform/windows/misc.cpp, both send() and send_batch() unconditionally attach an IP_PKTINFO control message pinning the source address:

IN_PKTINFO pktInfo;
SOCKADDR_IN saddr_v4 = to_sockaddr(send_info.source_address.to_v4(), 0);
pktInfo.ipi_addr    = saddr_v4.sin_addr;
pktInfo.ipi_ifindex = 0;
cm->cmsg_level = IPPROTO_IP;
cm->cmsg_type  = IP_PKTINFO;

With ipi_ifindex=0, Windows derives the outgoing interface from routing to the destination and then requires ipi_addr to be a unicast address assigned to that interface, else WSASendMsg returns WSAEINVAL. For a port-forwarded WAN client, send_info.source_address is not a locally-assigned address on the interface that routes to the client's public IP, so every packet is rejected. This is why LAN / native-IPv6 / mesh-VPN paths work (the dialed address is a real local interface address) but NAT port-forward does not. send() also has no fallback — on failure it just logs and returns false.

Suggested fix: on WSAEINVAL, retry without the IP_PKTINFO cmsg (plain send with no source pinning). A single-homed host doesn't need forced source selection — which is exactly why LAN already works. Small, low-risk change.

Adding a one-line debug log of send_info.source_address right before the WSASendMsg call would confirm the exact address being pinned on the WAN path. Happy to build a patched binary and test any fallback patch — the repro is deterministic.

Related: #3043 (closed as stale), #2120, ClassicOldSong/Apollo#1041 (open).

Host Operating System

Windows

Operating System Version

Windows 11, 10.0.26200

Architecture

amd64/x86_64

Package

Windows - msi installer (recommended)

GPU Type

NVIDIA

GPU Model

NVIDIA GeForce RTX 4060 Laptop GPU

GPU Driver/Mesa Version

610.62

Capture Method

Desktop Duplication API (Windows)

Apps

Log output

Online logs

<script src="https://gist.github.com/MathLeee/0302cb461bbb7b9fc52d7b86e8e7a073.js"></script>

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions