Reliable Roon endpoint discovery across subnets / sites (VLANs, SD-WAN, VPN) using a Layer-2 overlay
TL;DR: Roon discovers audio endpoints via broadcast + multicast (SOOD on UDP 9003) on the local subnet. If your Core and endpoints sit on different subnets or sites — VLANs, a mesh/SD-WAN like UniFi Site Magic, or a routed VPN — that discovery traffic doesn’t cross, so endpoints never appear, or appear sporadically and drop after sleep/reboot. The clean fix that requires no router/firewall changes: put the Core and the endpoints on the same virtual Layer-2 network with ZeroTier.
The symptom
-
Endpoints on a remote subnet don’t show in Settings → Audio, or show up occasionally and disappear after the endpoint sleeps/resumes or reboots.
-
You can reach the endpoint by IP (e.g.
Test-NetConnection <endpoint> -Port 9200succeeds), so it’s not a routing/firewall problem — it’s discovery.
Why it happens
-
Roon device discovery (SOOD) is broadcast
255.255.255.255:9003+ multicast239.255.90.90:9003. Routers, VLAN boundaries, and SD-WAN do not forward that traffic. -
Once the Core has discovered a device it caches the IP and reconnects by unicast (which does route). That’s why it “sometimes works” — you’re riding a past discovery until something (sleep/resume/reboot) forces a fresh one, which then fails to cross.
-
UniFi’s mDNS repeater does not help — that’s Bonjour (5353), not Roon’s SOOD (9003).
The fix — ZeroTier overlay
ZeroTier creates a virtual Ethernet (Layer-2) network across the internet and replicates broadcast/multicast between members, so the Core and endpoints act like they’re on one switch. (Use ZeroTier, not Tailscale — Tailscale is Layer-3 only and won’t carry Roon’s discovery.)
Only the Roon machines need it (Core + each endpoint you want discoverable):
-
Create a free network at my.zerotier.com → note the 16-char Network ID. Leave it Private, “Enable Broadcast” on (default).
-
Install ZeroTier One on the Core and each endpoint (Windows:
winget install ZeroTier.ZeroTierOne, or the MSI). -
Join the network on each machine (tray icon → Join Network → paste the ID, or
zerotier-cli join <NetworkID>). -
In the ZeroTier console, authorize each machine (tick “Auth”). Each gets an IP like
10.x.x.x. -
Restart Roon on each machine (RoonServer/RoonBridge/RAATServer, or just reboot). Important: Roon only binds discovery to network interfaces that exist when it starts, so it must be restarted after ZeroTier is joined.
That’s it — the Core now discovers the endpoints over the overlay and connects to their RAATServer (:9200) across it. Audio also streams over ZeroTier (RAAT is low-bandwidth; it’s peer-to-peer).
Bonus gotcha — Windows 11 endpoints with TLS errors in the log
If your RAATServer/RoonBridge log shows Could not create SSL/TLS secure channel when registering with discovery.roonlabs.net, your .NET Framework is defaulting to TLS 1.0 (which Win11 rejects). Fix in an Administrator PowerShell, then restart Roon:
$k='HKLM:\SOFTWARE\Microsoft\.NETFramework\v4.0.30319'
$k2='HKLM:\SOFTWARE\WOW6432Node\Microsoft\.NETFramework\v4.0.30319'
New-ItemProperty -Path $k -Name SystemDefaultTlsVersions -Value 1 -PropertyType DWord -Force
New-ItemProperty -Path $k -Name SchUseStrongCrypto -Value 1 -PropertyType DWord -Force
New-ItemProperty -Path $k2 -Name SystemDefaultTlsVersions -Value 1 -PropertyType DWord -Force
New-ItemProperty -Path $k2 -Name SchUseStrongCrypto -Value 1 -PropertyType DWord -Force
(Also watch out for VPN “threat protection” / HTTPS-inspection features — e.g. NordVPN — which intercept TLS and can break Roon’s cloud registration intermittently.)
How to verify
-
On an endpoint, its log should show discovery binding on the ZeroTier interface:
[discovery] [iface:ZeroTier ...] multicast recv socket is bound to 0.0.0.0:9003. -
Established connection to the endpoint’s
:9200from the Core’s ZeroTier IP. -
Endpoint zones appear in Settings → Audio; play to one; then sleep/resume the endpoint and confirm it comes back on its own.
Notes
-
This is independent of your router/SD-WAN — ZeroTier just needs internet (outbound UDP 9993). It also sidesteps overlapping-subnet problems since it uses its own address range.
-
Adding another endpoint later = install ZeroTier, join, authorize, restart Roon.