Pausing deployments¶
When a rollout looks wrong, the question is not "how do we undo firmware that's already on devices?" That ship has sailed. The question is "how do we stop offering it to anyone new, and how do we get a known-good build to the affected devices?".
SimpleOTA gives you two layers of defence: an automatic on-device safety net (SimpleOTAClient v0.2.0+, Arduino) and server-side levers you can pull for the whole fleet.
0. On-device automatic rollback (Arduino, v0.2.0+)¶
SimpleOTAClient v0.2.0 introduces trial-install rollback: after
apply() the library marks the new image as a trial and reverts to the
previous partition if confirmRunning() is not called within the
timeout. The rolled_back event is then reported to the server, which
auto-pauses the deployment (default: on, threshold 1) so no further
devices are offered the bad update.
For the full lifecycle, the timer-arming caveats, and the managed-mode auto-confirm behaviour, see the dedicated Trial install and rollback guide.
This is your first line of defence: a bad build is caught on the first
device that receives it. The manual Pause button in section 1 below covers
the cases where auto-pause does not apply: deployments with the auto-pause
toggle off, failure modes that do not surface as a rolled_back event, or
devices using firmware without trial-install support.
1. Pause¶
Go to the deployment and click Pause. From that moment:
- New
/check/requests behave as if the deployment didn't exist. - Devices already mid-download are not interrupted (the URL is short-lived but already issued).
- Cohort decisions are preserved; resuming later picks up exactly where you left off, same buckets, same seed.
Pause is always safe and always reversible. Use it as the first reflex when something looks off.
2. Roll forward with a fix¶
Pausing stops the bleed; it does not heal devices that already
flashed the bad build. Those devices are now reporting their new
current_build_number and need a higher build number to update
again.
The fix path:
- Build a corrected firmware. Bump nothing manually: the upload itself allocates a higher build number than anything previously uploaded in the project.
- Upload it.
- Create a deployment targeting the same audience as the broken one, at a high percentage (often 100 immediately, since the canary has already happened, badly).
- Pause or supersede the broken deployment.
3. Reverting via republish¶
If the latest build is broken and the previous one was fine, you can republish the previous binary as a new artifact (yes, with a new, higher build number; there's no rewinding). Upload it again, deploy it. The bytes on the device end up identical to the previous good release.
This is intentional: the integer comparison artifact.build_number >
device.current_build_number is the only comparison the engine does.
Republishing is how you tell the fleet "actually, go back to that".
4. What about devices that won't update?¶
If the bad build has bricked the OTA path itself (device can't reach
/check/ anymore), you're past what FOTA can fix.
For Arduino (SimpleOTAClient v0.2.0+): the trial-install timeout described in section 0 above covers the most common bricking scenario. If the bad firmware ships without trial support, physical re-flash is the only remaining option.
For ESP-IDF: esp_https_ota integrates with the bootloader's
rollback mechanism by default. We strongly recommend calling
esp_ota_mark_app_valid_cancel_rollback() only after a successful
health check (network up, sensors ok, serial heartbeat); never blindly
on boot.