A Zigbee2MQTT OTA check failing on one device with “Device didn’t respond to OTA request” is common enough that there’s already a dedicated troubleshooting guide for it. Power cycle the device, wake it right before retrying, confirm it’s actually online. But if Zigbee2MQTT OTA updates start failing on multiple devices at once, from different manufacturers, and none of the per-device fixes stick, the cause probably isn’t any of those devices. Something else on the mesh is answering a question it shouldn’t.
This is a protocol-level failure mode in how Zigbee devices locate their OTA upgrade server, not a Zigbee2MQTT bug, and it happens entirely on the local mesh. No cloud service, no bridge restart, no coordinator firmware issue. One well-documented case, a batch of SONOFF ZBM5-3C-80/86 switches on a buggy firmware build, shows exactly how a single misbehaving device can block updates for everything else on the network.
Is this really network-wide, or just one flaky device?
Before chasing a rogue device, rule out the boring explanation. A single unresponsive device, especially a battery sensor asleep most of the time, fails OTA checks routinely, and that’s a different problem covered in the per-device troubleshooting guide above. The useful test is whether unrelated devices, different manufacturers, different device types, a sensor and a plug and a switch that have nothing in common except sharing the mesh, all start failing OTA checks around the same time. If it’s always been the same flaky bulb, that’s per-device. If your Aqara sensor, your IKEA bulb, and your Sonoff switch all start failing OTA checks that used to work, something on the network is answering for all of them.
Check whether the failures line up with a recent change on the network: a new device joining, or an existing device taking a firmware update. If OTA checks were working fine until that change, the device involved is the first thing worth suspecting.
| Symptom | Single flaky device | Network-wide OTA discovery hijack |
|---|---|---|
| Which devices fail | One device, same one every time | Multiple unrelated devices, different brands |
| Started after | No clear trigger, or a known weak-signal device | A device joining the network, or an existing device updating its firmware |
| Power cycle target device | Often fixes it for good | Can succeed once, then fail again later |
| Removing the suspect device | Not applicable, it’s the one failing | Restores normal OTA discovery for everyone else |
How a Zigbee device finds its OTA server
OTA firmware distribution in Zigbee runs over the OTA Upgrade Cluster, defined in Zigbee Alliance document 095264. Two roles matter. The OTA server holds firmware images; in a Zigbee2MQTT setup that’s Zigbee2MQTT itself, working through the coordinator. The OTA client is the device receiving the firmware. The client isn’t told where its upgrade server lives. It finds one itself by sending a ZDO Match Descriptor Request asking who implements cluster 0x0019, the OTA cluster, as a server. The request can be unicast, but sent as a broadcast it reaches the whole mesh. Any node that responds identifies itself as an upgrade server, and if more than one node answers, the client uses whichever response arrives first. There’s no priority list, no coordinator preference, and no check on whether the responder is actually supposed to be a server. Silicon Labs’ Zigbee SDK documentation on OTA bootload server and client setup walks through the same discovery-and-first-responder rule the spec defines.
That design assumes every device on the network correctly declares which side of the OTA cluster it implements. Most devices get this right, and the discovery step stays invisible. It only becomes a problem when one doesn’t.
The SONOFF ZBM5-3C-80/86 case
A GitHub issue opened against Zigbee2MQTT on 2026-09-22, open at the time of writing (#33185 in the Koenkk/zigbee2mqtt repository), documents exactly that failure. SONOFF ZBM5-3C-80/86 switches running firmware 1.0.6 advertise the OTA cluster, 0x0019 (genOta in Zigbee2MQTT’s naming), as an input cluster on endpoint 3. In Zigbee’s client-server model, an input cluster means “this device implements the cluster as a server.” The switch is an OTA client, and it correctly lists genOta as an output cluster on endpoint 1. On 1.0.6 it presents both sides at once. Units on firmware 1.0.4 don’t carry the extra entry, according to the report. Zigbee2MQTT records each endpoint’s input and output cluster lists during the device interview, so the bad entry is visible in its own data.
The reporter in that issue had nine of the affected switches on their network and saw OTA checks fail on roughly 20 other, unrelated devices. The failures showed the familiar “Device didn’t respond to OTA request” error, timing out after around 60 seconds, on devices that were online, paired correctly, and otherwise working fine. The count matters. Every ZBM5 unit on the network is another node that can answer a client’s discovery request before the coordinator does.
This has only been reported for this specific SONOFF model and firmware build so far. It’s a real, sourced case of a general Zigbee-spec-level failure mode, not evidence that SONOFF firmware is broadly unreliable or that other SONOFF devices carry the same bug.
Why Zigbee2MQTT can’t fix this in software
The Zigbee2MQTT maintainer’s read, in the same GitHub thread, is that the software can’t patch around this. Follow the roles through. When Zigbee2MQTT checks a device for an update, the device is supposed to query its upgrade server for a new image. A device that discovered a ZBM5 as its server sends that query to the ZBM5 instead. Zigbee2MQTT never hears it, waits, and reports “Device didn’t respond.” The client devices are doing exactly what the spec tells them to do, and Zigbee2MQTT is behaving correctly as a server. The bug sits entirely in the switch: a non-coordinator node answering a discovery request it has no business answering.
I think this points at a gap in the OTA discovery step itself, not just a one-off firmware mistake. First-response-wins with no check on who is allowed to respond means the whole network’s OTA reliability depends on every device declaring its cluster roles correctly, and nothing in that step catches a device that gets it wrong.
What actually fixes it
There’s no Zigbee2MQTT config change that resolves this, because the failure is in which node the client devices send their queries to, and Zigbee2MQTT isn’t that node. A few things do work, with different tradeoffs.
Identify the suspect device first. Check which devices joined the network, or took a firmware update, around when the OTA failures started, and look at their cluster lists. The zigbee2mqtt/bridge/devices topic (how Zigbee2MQTT’s MQTT topics are laid out) and the frontend’s device view both show each endpoint’s input and output clusters from the interview data. genOta in the input list of anything other than the coordinator is the red flag. The network map view is a fast way to see every device actually present on the mesh, not just the ones you remember pairing.
Power-cycling the affected target device can get one OTA check through, because it makes the device run discovery again and the coordinator’s response may arrive first this time. That’s not a fix. It’s a race that happens to go the right way sometimes. The rogue device is still on the network and can win the next one.
Taking the misbehaving device off the network is the fix that holds. It needs to actually leave the mesh, which in the reported case meant physically removing the units; a device that has only been deleted from Zigbee2MQTT’s database but is still powered and joined can keep answering. Once it’s gone, OTA checks on the other devices returned to normal right away, according to the reporter’s account.
Binding the OTA cluster to the coordinator does not fix this. OTA discovery uses the client’s own Match Descriptor request, not the binding table, so a binding entry has no effect on which device answers first.
If you’re troubleshooting a coordinator or mesh issue in general rather than this specific discovery problem, the coordinator firmware update guide and the many-to-one routing failure writeup cover two other, unrelated causes of mesh instability that can look similar without any device hijacking OTA discovery.
Common questions
- Why does Zigbee2MQTT say a device didn’t respond to OTA when it’s online and working fine? Because the device may be sending its update query to a different node. If another device answered its OTA server discovery first, the query goes there, and Zigbee2MQTT times out waiting.
- Can one Zigbee device really block firmware updates for others on the same network? Yes, per the SONOFF ZBM5 case above. Any device that incorrectly advertises cluster 0x0019 as a server can win discovery requests meant for the real server.
- Does removing the problem device fix OTA immediately, or does it need a coordinator restart? Per the reported case, removal alone restored normal discovery. No coordinator restart was needed.
- Is this a Zigbee2MQTT bug or a device firmware bug? Firmware. The client devices follow the spec’s discovery rule and Zigbee2MQTT behaves correctly as the server; the faulty device is the one claiming a role it doesn’t have.
- How do I tell if my OTA failures are per-device or network-wide? Check whether unrelated devices, different brands and device types, are all failing at once. See the comparison table above.
What this covers, and what’s still open
This article is built from the Zigbee OTA Upgrade Cluster spec, via Silicon Labs’ SDK documentation, and from one open GitHub issue, not from a reproduction on this site’s own network. The discovery mechanism, first response wins, is documented protocol behavior and applies to any Zigbee network running OTA updates, regardless of coordinator or stack. The SONOFF ZBM5-3C-80/86 case is one confirmed, currently open report against firmware 1.0.6, not evidence of a wider pattern across SONOFF’s product line.
The entire mechanism stays local. Discovery, the rogue response, and the workaround of removing the device all happen over the Zigbee mesh itself, with no cloud dependency and no vendor service that needs to be up.
What still depends on SONOFF is a firmware fix. The issue outlines two directions: stop advertising the OTA server cluster on client firmware, or have the switch answer image queries with “no image available” so clients move on to a real server. As of this writing, no fixed firmware version is referenced in the issue.
On your own network, if OTA checks are failing on multiple unrelated devices, check what’s joined or updated recently and look for genOta in its input clusters. If you’re running ZBM5-3C-80/86 units on firmware 1.0.6, that’s the first place to look. If SONOFF patches this, that specific trigger goes away, but the discovery mechanism doesn’t change, and nothing stops a different manufacturer’s firmware from making the same mistake next.
