Zigbee2MQTT Can Now Abort a Stuck OTA. Here’s Why I Still Update One Device at a Time.

Close-up of a green printed circuit board, representing device firmware

For the better part of two years my Zigbee firmware policy was a single word: don’t. If a sensor reported temperature and a switch switched, I left the firmware exactly where it was and slept fine. Zigbee over-the-air updates have a reputation, and it’s earned — they’re slow, they flood the mesh with traffic, and when one goes sideways you can be left with a device that’s neither on the old firmware nor the new one. So I avoided them.

Then Zigbee2MQTT 2.12.0 landed on June 9th with one small line in the changelog that made me reopen the whole question: you can now abort a running OTA update. It’s a tiny feature. But it changed the math on a risk I’d been treating as all-or-nothing, and it’s a good excuse to write down the actual rules I follow now — because “never update” was never a real policy, just a way of avoiding a decision.

This is a build log from one home, documented honestly. Nothing here is sponsored, and there are no affiliate links in this post — just the steps I’d want a friend to know before they touch firmware on a device they rely on.

What actually changed in 2.12.0

The headline addition is an abort path. In Zigbee2MQTT you start an update by publishing to zigbee2mqtt/bridge/request/device/ota_update/update with the device’s name or address. As of 2.12.0 there’s a matching .../ota_update/update/abort topic that takes the same payload and stops a transfer that’s in progress. In the frontend it shows up as a button next to the progress bar, so you don’t have to touch MQTT by hand.

Why does a stop button matter so much? Because the failure mode I was most afraid of wasn’t a bad firmware — it was a transfer that crawls. A Zigbee OTA can take anywhere from ten minutes to well over an hour depending on the device and how busy your mesh is, and during that whole time the update is adding heavy traffic to the network. Before, if you kicked one off at a bad moment — right as everyone got home, lights and motion sensors all chattering — your only real options were to let it grind or restart Zigbee2MQTT and hope. Now you can call it off cleanly and try again when the network is quiet. That’s the difference between an irreversible commitment and a reversible experiment, and reversible experiments are the ones I’m willing to run.

To be clear about what abort is not: it doesn’t roll a half-flashed device back to a known-good state, and it isn’t a recovery tool for a device that’s already wedged. It’s a way to stop a transfer you don’t want to finish. Useful, but it doesn’t repeal the rest of the rules.

The part nobody warns you about: the reboot

Here’s the detail buried in the Zigbee2MQTT docs that bit me the first time and that I now repeat to anyone who asks. When an OTA finishes, the device reboots into the new firmware — and depending on its power-on behaviour, that reboot can switch a relay on or flash a light. The docs say it plainly: the reboot “may cause unwanted interruptions or turn-ons.” Picture updating a bedroom light’s firmware at 11pm and having it blink to full brightness as it comes back up. Funny once, then never again.

There’s a second surprise in the same paragraph. Because a firmware update can change what a device can do, Zigbee2MQTT treats a completed OTA a lot like pairing a brand-new device: it re-interviews the device to detect new capabilities and re-configures it. That re-configuration can overwrite custom reporting intervals with the defaults. If you’ve carefully tuned a sensor to report every two minutes instead of every ten, an update can quietly reset that, and you won’t notice until your automations feel sluggish a week later. So the post-update checklist isn’t just “did it survive” — it’s “did my custom settings survive.”

A collection of smart home devices
Smart-home gear that runs on firmware you can choose to update — or not. Photo: Pexels

My actual rules now

So I’m no longer a “never update” person. I’m a “update deliberately, one device at a time” person. The rules are boring on purpose:

Read the release notes first. A firmware update can fix a real bug or close a security hole — or it can change behaviour in a way that breaks compatibility. The Zigbee2MQTT update check now surfaces release notes when the source provides them, so there’s less excuse to flash blind. If I can’t find out what a version changes, I don’t install it. “Newer” is not a reason.

One device at a time, when the house is quiet. The official guidance is to update a single device while the network is in low demand, and it’s right. I do firmware in the late morning on a weekday when nobody’s home and the mesh is idle — never in the evening when motion sensors and switches are all talking. Batch updates are how you turn one slow transfer into a network-wide traffic jam.

Check the battery on battery-powered devices. OTA is power-hungry. The docs recommend 70% or more, and some devices will simply refuse to update below a threshold. A flat coin-cell mid-transfer is exactly the kind of bad ending you don’t want, and it’s completely avoidable.

Wake the device right before you start. Battery devices sleep, and a sleeping device won’t respond to a manual update request. A button press right before triggering wakes it; for the stubborn ones (some Legrand models are famous for this) there’s a “schedule” option that runs the update the next time the device itself checks in.

Re-check custom settings afterward. Because of the re-interview, I now treat every successful update as a prompt to glance at that device’s reporting config and any binds, and put them back if they’ve reverted.

So do you actually need to update?

This is the local-first question underneath all of it. A lot of the smart-home world is built on the assumption that you should always be on the latest everything, because the cloud decides for you anyway. Running Home Assistant bare-metal with a local Zigbee mesh means I get to decide instead — and most of the time the honest answer is that a working device on stable firmware doesn’t need touching. I update when there’s a named bug fix or security reason that applies to me, not on a schedule and not for the version number.

What 2.12.0’s abort button really changed isn’t how often I update — it’s how much dread is attached to each one. Knowing I can stop a transfer that’s misbehaving turns firmware from a one-way door into something closer to the rest of my local setup: try it, watch it, back out if it’s wrong. That’s the whole reason I went local in the first place. It’s nice to see the tooling catch up to the philosophy.

If you’ve been avoiding Zigbee firmware updates the way I was, you don’t have to flip all the way to “update everything.” Pick one non-critical device, read its notes, do it on a quiet morning, and keep the abort button in your back pocket. That’s a policy I can actually live with.

Sources: the Zigbee2MQTT OTA updates documentation and the Zigbee2MQTT release notes on GitHub.

Leave a Reply

Your email address will not be published. Required fields are marked *