Flash the OTAFIX bootloader
Guide · updated June 2026
Stock nRF52 bootloaders make over-the-air updates a coin flip. OTAFIX — a community fork of the Adafruit nRF52 bootloader — fixes that, so you can push new MeshCore firmware to a node over Bluetooth, reliably — even a repeater bolted to a roof you’d rather not climb.
What a bootloader even is
The bootloader is the tiny program that runs the instant your board powers on, before the actual MeshCore firmware. Its main job is to hand control to your firmware — but it’s also the part that accepts new firmware when you update. Flash over USB (the drag-and-drop UF2 drive) or push a build over Bluetooth (OTA DFU — Over-The-Air Device Firmware Update): both go through the bootloader.
That last part is where the trouble lives. The bootloader that ships on most nRF52 boards — and the ancient one RAK puts on the RAK4631 — handles OTA badly or not at all. OTAFIX is a community fork (by oltaco) that rolls in long-ignored fixes so OTA actually works, and works fast.
Why you’d want it
One reason, mostly: updating a node you can’t easily reach. A repeater on a mast or a roof shouldn’t need a ladder and a laptop every time there’s a new firmware build. With OTAFIX you walk up with a phone, connect over Bluetooth, and push the update.
What the fork actually changes under the hood:
- Won’t get stuck. If there’s no valid firmware on the board, it falls back to OTA DFU mode and waits for an update — instead of stranding you.
- Much faster OTA — high-MTU BLE moves bigger chunks per packet.
- Lazy flash erase — erases pages on demand, so it starts faster.
- Better iOS behaviour — small packets get combined, which iPhones need.
- Auto-boots into the app after an OTA update over USB — no manual reset.
- Board-specific BLE name in DFU mode (e.g.
RAK4631_DFU) instead of a genericAdaDFU, so you connect to the right one.
On the RAK4631 specifically, OTAFIX is built on Adafruit bootloader 0.9.2 — far newer than the 0.6.2-11 RAK still ships from the factory.
Does this apply to my board?
OTAFIX is for nRF52840 boards only. If your node is an ESP32 (Heltec V3, most cheap LoRa32 boards), it doesn’t use this bootloader at all — skip this guide.
Supported nRF52840 boards include:
- RAK — RAK4631, RAK WisMesh Tag
- Heltec — Mesh Node T114
- Seeed — XIAO nRF52840 (BLE and Sense variants), T1000-E card tracker, SenseCAP Solar Node P1, Wio Tracker L1
- LilyGO — T-Echo
- Elecrow — ThinkNode M1 / M3 / M6
- ProMicro nRF52840 (Nologo and clones) — these never did OTA on the stock bootloader
- Minewsemi MX25LE01
Seeed XIAO ships in two flavours — a plain BLE board and a Sense board. Use the matching variant. Pop into UF2 mode and open INFO_UF2.TXT if you’re not sure which you have.
Back up first — this wipes the node
Here’s the part people miss: after you flash the new bootloader, MeshCore needs a full device erase to clean out its storage area (more on that below). That erase wipes your node’s identity — including its private key. A wiped node comes back as a stranger: new Public ID, repeater needs re-adopting, references break.
Run get prv.key and save your rebuild kit before you touch the bootloader. Walk through it in the MeshCore backup & key security guide — then come back here. If you skip this, that identity is gone for good.
Flashing the bootloader
The easy path is the UF2 file — no command line, just drag and drop.
-
Grab the right UF2
Easiest: open flasher.meshcore.io, pick your device, and download its bootloader file — the filename starts with
update-(e.g.update-rak4631.uf2). You can also grab it straight from the project’s GitHub releases. -
Enter UF2 mode
Double-press the reset button within about half a second. A USB drive pops up on your computer. (A few boards are fiddly — the Seeed T1000-E and Elecrow ThinkNode M3 use a magnetic cable and a long button hold; check the project README for those.)
-
Drag the file across
Copy the
update-xxxx.uf2onto that USB drive. The board flashes the new bootloader and reboots on its own. The drive will disappear — that’s expected. -
Confirm it took
Double-press reset again to re-enter UF2 mode and open
INFO_UF2.TXT. You should now see OTAFIX in the bootloader name. Done — the bootloader is in.
Flashed the wrong file or bricked the UF2 drive? The bootloader can also be written with the adafruit-nrfutil command-line tool using a full bootloader + SoftDevice package — see the project README for that recovery path.
The erase step that catches everyone
A new bootloader changes how the board lays out its storage, so MeshCore needs its data area — the ExtraFS region — fully wiped, or the node misbehaves after the update.
You have to use the MeshCore web flasher to do this erase. It points you at the correct erase firmware for your specific board:
- Go to flasher.meshcore.io and choose the erase option for your device.
- Run it, then flash your MeshCore firmware fresh (companion or repeater).
- Restore your identity from your rebuild kit —
set prv.key, region, path-hash mode, passwords. (Full restore steps are in the backup guide.)
Generic erase tools won’t work. Only the MeshCore web flasher’s erase clears the ExtraFS area — other “erase” firmwares leave it behind and your node won’t come up clean.
Updating over the air
With OTAFIX in place, future firmware updates can go over Bluetooth — connect to the node from the MeshCore app or web flasher, pick the new firmware, and let it push. If an OTA update is interrupted, the board now drops into OTA DFU mode and waits for you to retry rather than bricking.
“My board has no USB drive and no serial port!”
That’s the new behaviour, not a fault. When there’s no valid firmware installed, OTAFIX sits in OTA DFU mode, advertising over Bluetooth as something like RAK4631_DFU — waiting for an update. To get the USB drive / serial port back, just double-press reset to force UF2 mode, or finish an OTA update.
Sources & links
Everything here is drawn straight from the project and the MeshCore blog.
New to nodes and repeaters? Start with Set up your first MeshCore node and Set up a MeshCore repeater.
Updating a repeater the hard way?
Bring it to #meshcore — someone here has flashed the board you’re holding.