Sonos Discovery Issues

I seem to have lost some of the Sonos devices on my network within Roon running Roon Server version 2.0 build 1357. Note that all of the devices are discovered and fully functional in Sonos, Control4, and Spotify.

This for whatever reason appears to be related to discovering the devices in the bottom half of my layer 2 network which is 192.168.86.0/23. Roon discovers everything in the 192.168.86.0/24 potion of the network but seems to have lost the ability to properly discover devices in the 192.168.87.0/24 portion of the network.

I have confirmed that my Roon Server device (Ubuntu 22.04) has the proper subnet for the /23 of 255.255.254.0 (set via static DHCP), as does all of my Sonos devices. I see the SSDP (port 1900) traffic from all of the Sonos devices via tcpdump on the Roon Server device. I also see all of the Sonos zones in the Roon Server logs in the zone update trace log. However, the only zones that actually appear in Roon → Settings → Audio are those in the 192.168.86.0/24 portion of the network.

I’ve tried to restart RoonServer and have power cycled some of the undiscoverable Sonos devices without any luck. Any help would be much appreciated.

Roon is only supported in a single subnet range as it depends on a broadcast protocol. Everything would have to be on 86.

@ged_hickman1,

My subnet is a /23 with a netmask of 255.255.254.0 which is a single subnet that ranges from 192.168.86.0 to 192.168.87.255.

It’s also worth noting that the Roon Service device has the IP address of 192.168.87.127 so if there was an incorrect subnet mask I would expect it to find the devices in 192.168.87.0-255 vs 192.168.86.0-255.

As I mentioned I see the Sonos broadcast just fine via tcpdump on the Roon Server device.

This was working prior, the last log referencing these additional Sonos zones was on December 21st:

‘12/21 02:41:24 Trace: [roonapi] [apiclient 192.168.86.33:49531] CONTINUE Changed’,

The next CONTINUE Changed log I have was the next day which appears to delete all zones:

12/23 04:16:07 Trace: [roonapi] [apiclient 192.168.86.33:46957] GOT com.roonlabs.transport:2/subscribe_zones {"subscription_key":"[redacted]"}

12/23 04:16:07 Info: [roonapi/transport] activating zone subscriptions

12/23 04:16:07 Trace: [roonapi] [apiclient 192.168.86.33:46957] CONTINUE Subscribed {"zones":[]}

That’s followed by Sonos discovery which only adds devices on 192.168.86.0-255, each block looks like the following, where a FOUND log for added devices is followed up with “found” that lists every one of my visible Sonos devices which are subsequently not added w/ the FOUND log.

12/23 04:16:34 Trace: [songcastdirect] using subnet 56a8c0 192.168.86.0

12/23 04:16:34 Trace: [raat] [sood] Refreshing device list

12/23 04:16:34 Trace: [raatserver] [sood] Refreshing device list

12/23 04:16:34 Trace: [songcastdirect] using subnet 56a8c0 192.168.86.0

12/23 04:16:34 Trace: [devicemanager/sonos] FOUND Device IP=192.168.86.77 UDN=uuid:RINCON_38420B29AC6B01400 Manufacturer=Sonos, Inc. ModelName=Sonos Amp ModelNumber=S16

12/23 04:16:34 Warn: [client/sonos] Client created for id: uuid:RINCON_38420B29AC6B01400

12/23 04:16:34 Trace: [device/sonos] [sonos] device constructor, UDN: uuid:RINCON_38420B29AC6B01400 modelname: AMP remoteIP: 192.168.86.77

12/23 04:16:34 Debug: [easyhttp] [26] POST to https://api.roonlabs.net/discovery/1/query returned after 177 ms, status code: 200, request body size: 74 B

12/23 04:16:34 Trace: [devicedb] [autodetect] No Match for DeviceAutodetectData[Type=Sonos Vendor=Sonos Model=AMP]

12/23 04:16:34 Trace: [devicemanager/sonos] found device UUID: RINCON_38420B29AC6B01400 from zone state, searching by ip: 192.168.86.77

12/23 04:16:34 Trace: [devicemanager/sonos] found device UUID: RINCON_38420B2CA56C01400 from zone state, searching by ip: 192.168.87.13

12/23 04:16:34 Trace: [devicemanager/sonos] found device UUID: RINCON_38420BF1652801400 from zone state, searching by ip: 192.168.87.94

12/23 04:16:34 Trace: [devicemanager/sonos] found device UUID: RINCON_542A1BD55BE001400 from zone state, searching by ip: 192.168.86.82

12/23 04:16:34 Trace: [devicemanager/sonos] found device UUID: RINCON_38420BF6DFFE01400 from zone state, searching by ip: 192.168.86.167

12/23 04:16:34 Trace: [devicemanager/sonos] found device UUID: RINCON_F0F6C17FA65901400 from zone state, searching by ip: 192.168.87.38

12/23 04:16:34 Trace: [devicemanager/sonos] found device UUID: RINCON_38420B68CC7A01400 from zone state, searching by ip: 192.168.87.188

12/23 04:16:34 Trace: [devicemanager/sonos] found device UUID: RINCON_38420B2CEE2C01400 from zone state, searching by ip: 192.168.87.176

12/23 04:16:34 Trace: [devicemanager/sonos] found device UUID: RINCON_38420B2E05A701400 from zone state, searching by ip: 192.168.87.242

12/23 04:16:34 Trace: [devicemanager/sonos] found device UUID: RINCON_38420B2E0A4201400 from zone state, searching by ip: 192.168.87.136

12/23 04:16:34 Trace: [devicemanager/sonos] found device UUID: RINCON_F0F6C1935A5701400 from zone state, searching by ip: 192.168.87.112

12/23 04:16:34 Trace: [devicemanager/sonos] found device UUID: RINCON_48A6B822287001400 from zone state, searching by ip: 192.168.86.85

12/23 04:16:34 Trace: [devicemanager/sonos] found device UUID: RINCON_48A6B847F44301400 from zone state, searching by ip: 192.168.86.243

12/23 04:16:34 Trace: [devicemanager/sonos] found device UUID: RINCON_38420B2CE90A01400 from zone state, searching by ip: 192.168.87.147

12/23 04:16:34 Trace: [devicemanager/sonos] found device UUID: RINCON_38420B68CC5601400 from zone state, searching by ip: 192.168.87.152

I unfortunately do not have logs that go back prior to my RoonServer upgrade, but is it possible the Sonos discovery logic was changed?

For reference here are the SSDP broadcasts as captured from the Roon Server device:

root@roon-server:~# tcpdump -n -i eno1 'port 1900' 2>&1 > /tmp/sonos_broadcasts

tcpdump: verbose output suppressed, use -v[v]... for full protocol decode

listening on eno1, link-type EN10MB (Ethernet), snapshot length 262144 bytes

^C726 packets captured

740 packets received by filter

0 packets dropped by kernel

root@roon-server:~# cat /tmp/sonos_broadcasts | awk '{ gsub("\.[0-9]*$", "", $3); print $3 }' | sort | uniq

192.168.86.1
192.168.86.162
192.168.86.167
192.168.86.177
192.168.86.187
192.168.86.217
192.168.86.232
192.168.86.33
192.168.86.50
192.168.86.52
192.168.86.77
192.168.86.81
192.168.86.82
192.168.86.83
192.168.86.85
192.168.86.86
192.168.86.92
192.168.87.1
192.168.87.106
192.168.87.127
192.168.87.129
192.168.87.136
192.168.87.147
192.168.87.176
192.168.87.188
192.168.87.22
192.168.87.94

tl;dr Roon Server depends on the Sonos GetZoneGroupState API call which fails for large Sonos installations of 20 or more devices due to a 16KB buffer limitation. Other solutions work around that limitation by using the subscriptions API against each Sonos device to get the device state. A reference implementation is here:

It would be great if Roon would implement the same design approach so large Sonos installations can properly discover their Sonos Streaming devices.

The details are below:

After more debugging I apparently have two issues going on. First, @ged_hickman1 was right, apparently I had restored homebridge from a backup which added a second interface eno1:1 that was configured as 192.168.86.127/24 which RoonServer picked up as the primary interface. I came acorss this when looking at the Settings screen in the UI and noticed the IP address of my Roon Server was not the address of my primary interface.

I’ve removed the secondary interface, restarted Roon, and now it discovers all of my Sonos devices but only as AirPlay end-points but not as Sonos Streaming end points.

I happened to notice that my installation of sonos2mqtt was also failing to discover devices with the following error:

# Startup error. Sonos error on GetZoneGroupState UPnPError 501 (Action failed)

Which led me to this thread on mqtt2sonos: Startup error. Sonos error on GetZoneGroupState UPnPError 501 (Action failed) · Issue #134 · svrooij/sonos2mqtt · GitHub, and later this thread on Home Assistant: Sonos : UPnP Error 501 and Large Sonos Installations · Issue #82513 · home-assistant/core · GitHub

The issue is with large Sonos installations with 20 or more devices the GetZoneGroupState fails (status code 501) as it appears to be limited a 16KB buffer. I was able to confirm that Roon Server is failing this call through tcpdump capture and then restarting the Roon Server:

11:13:11.569028 IP roon-nuc.localdomain.52274 > 192.168.86.243.1400: Flags [P.], seq 1:576, ack 1, win 502, options [nop,nop,TS val 2950699681 ecr 128732], length 575
E..s~.@.@.....W...V..2.x,..j
.-A....2).....
........POST /ZoneGroupTopology/Control HTTP/1.1
Host: 192.168.86.243:1400
SOAPAction: "urn:schemas-upnp-org:service:ZoneGroupTopology:1#GetZoneGroupState"
Connection: Keep-Alive
Content-Type: text/xml; charset="utf-8"
Content-Length: 336

<?xml version="1.0" encoding="utf-8"?>
<s:Envelope s:encodingStyle="http://schemas.xmlsoap.org/soap/encoding/" xmlns:s="http://schemas.xmlsoap.org/soap/envelope/">
        <s:Body>
                <u:GetZoneGroupState xmlns:u="urn:schemas-upnp-org:service:ZoneGroupTopology:1">
                        <InstanceID>0</InstanceID>
                </u:GetZoneGroupState>
        </s:Body>
</s:Envelope>
11:13:11.570694 IP 192.168.86.243.1400 > roon-nuc.localdomain.52274: Flags [.], ack 576, win 236, options [nop,nop,TS val 128732 ecr 2950699681], length 0
E..4..@.@./c..V...W..x.2
.-A,.......MS.....
........
11:13:11.572604 IP 192.168.86.243.1400 > roon-nuc.localdomain.52274: Flags [P.], seq 1:523, ack 576, win 236, options [nop,nop,TS val 128732 ecr 2950699681], length 522
E..>..@.@.-X..V...W..x.2
.-A,.......2......
........HTTP/1.1 500 Internal Server Error
CONTENT-LENGTH: 347
CONTENT-TYPE: text/xml; charset="utf-8"
EXT:
Server: Linux UPnP/1.0 Sonos/76.2-47270 (ZPS14)
Connection: close

From what I can tell Roon Server appears to be silent on this failure and does not proceed adding Sonos Streaming devices discovered via SSDP. I did however remove a few Sonos devices by powering them off, resetting the device that Roon Server was using as the coordinator for the GetZoneGroupState call, confirmed directly that the GetZoneGroupState succeeds via command line, and restarted the Roon Server. Roon was able to properly discover all of the devices as Sonos Streaming devices.

Both mqtt2sonos and HA sonos integration were redesigned to work around the GetZoneGroupState limitation by using the subscriptions API against each device, reference implementation is below:

Here is a link to the node-sonos change to support falling back to events/subscription when GetZoneGroupState fails: