RAK4630 nrfutil upload problem

Hi,

I have some RAK4630 modules that are only accessible with a USB interface for updating. Not possible to access programming pins with JLINK or RAKDAP1.

Some time ago, I develop an script for updating them in PC with Windows 11:

  1. Switch to AT mode (since they are configured with RAK_CUSTOM_MODE)
  2. Set to boot mode with AT+BOOT
  3. Run nrfutil tool to update with compiled file in .zip

Now, this is not working anymore, nrfutil DFU upload consistently gets stuck at approximately 60% of the transfer process. As process is not completed, application becomes corrupted. I managed to recover the module by using the VS Code IDE with Arduino extension (arduino-cli upload). From the IDE, it always works.

Tests performed

  1. Running from the terminal the same arduino-cli upload command with and without elevated privileges: arduino-cli upload --fqbn rak_rui:nrf52:WisCoreRAK4631Board --port COM6
  2. Using three different units.
  3. Using nrfutil alone. Downloaded from: RAKWireless docs.
  4. In a different PC running Ubuntu and using the nrfutil installed with pip3.
  5. Tried different RUI3 release.
  6. Killing conflicting processes (e.g. VS Code, Arduino IDE, serial monitors, terminals, etc.).
  7. Lowering the serial baud rate.
  8. Tried different USB cables.

In all cases, it fails at about 60% of the process, so it starts programming but never ends correctly. As mentioned before, only working from VS Code IDE, probably from Arduino IDE as well but I haven’t checked.

Questions:

  1. Why does arduino-cli upload work flawlessly while nrfutil DFU hangs at 60%?
  2. What upload mechanism does arduino-cli use that differs from nrfutil DFU?
  3. Are there known timing issues with the RAK4630 bootloader specific to nrfutil?
  4. Should I be using a different version of nrfutil or different upload parameters?
  5. Is the 60% failure point indicative of a specific issue (e.g., memory page, flash sector boundary)?

Terminal output:

2026-02-10 13:23:52,965 Using board at serial port: COM6
2026-02-10 13:23:52,972 Sending Application image.
2026-02-10 13:23:56,480 Serial: Set Packet Receipt Notification 0
2026-02-10 13:23:56,482 Sending init packet...
2026-02-10 13:23:56,482 Serial: Selecting Object: type:1
2026-02-10 13:23:56,483 Serial: Object selected:  max_size:512 offset:0 crc:0
2026-02-10 13:23:56,484 Serial: Streaming Data: len:141 offset:0 crc:0x00000000
2026-02-10 13:23:56,675 Sending firmware file...
2026-02-10 13:23:56,676 Serial: Selecting Object: type:2
2026-02-10 13:23:56,677 Serial: Object selected:  max_size:4096 offset:0 crc:0
2026-02-10 13:23:56,761 Serial: Streaming Data: len:4096 offset:0 crc:0x00000000
2026-02-10 13:23:56,918 Serial: Streaming Data: len:4096 offset:4096 crc:0x47DC8DB3
2026-02-10 13:23:57,074 Serial: Streaming Data: len:4096 offset:8192 crc:0xE78B8836
2026-02-10 13:23:57,232 Serial: Streaming Data: len:4096 offset:12288 crc:0x1A50BC58
2026-02-10 13:23:57,389 Serial: Streaming Data: len:4096 offset:16384 crc:0xF2D3FF75
2026-02-10 13:23:57,546 Serial: Streaming Data: len:4096 offset:20480 crc:0xAC991E42
2026-02-10 13:23:57,703 Serial: Streaming Data: len:4096 offset:24576 crc:0x18B96099
2026-02-10 13:23:57,860 Serial: Streaming Data: len:4096 offset:28672 crc:0xFA9A2DDE
2026-02-10 13:23:58,017 Serial: Streaming Data: len:4096 offset:32768 crc:0x07373EFD
2026-02-10 13:23:58,174 Serial: Streaming Data: len:4096 offset:36864 crc:0xB6766845
2026-02-10 13:23:58,331 Serial: Streaming Data: len:4096 offset:40960 crc:0xB8C6393E
2026-02-10 13:23:58,488 Serial: Streaming Data: len:4096 offset:45056 crc:0x1E9FAC7E
2026-02-10 13:23:58,645 Serial: Streaming Data: len:4096 offset:49152 crc:0xEEC55ECB
2026-02-10 13:23:58,802 Serial: Streaming Data: len:4096 offset:53248 crc:0x7F23EFDE
2026-02-10 13:23:58,958 Serial: Streaming Data: len:4096 offset:57344 crc:0xACA75382
2026-02-10 13:23:59,115 Serial: Streaming Data: len:4096 offset:61440 crc:0x9A934FD7
2026-02-10 13:23:59,272 Serial: Streaming Data: len:4096 offset:65536 crc:0x670D90F3
2026-02-10 13:23:59,429 Serial: Streaming Data: len:4096 offset:69632 crc:0x6C06BABE
2026-02-10 13:23:59,587 Serial: Streaming Data: len:4096 offset:73728 crc:0x75E61D80
2026-02-10 13:23:59,744 Serial: Streaming Data: len:4096 offset:77824 crc:0x0D3ED0DC
2026-02-10 13:23:59,901 Serial: Streaming Data: len:4096 offset:81920 crc:0x22AB4BA7
2026-02-10 13:24:00,057 Serial: Streaming Data: len:4096 offset:86016 crc:0xC1A93B17
2026-02-10 13:24:00,214 Serial: Streaming Data: len:4096 offset:90112 crc:0xF39F6CDB
2026-02-10 13:24:00,372 Serial: Streaming Data: len:4096 offset:94208 crc:0x52E7DF2B
2026-02-10 13:24:00,529 Serial: Streaming Data: len:4096 offset:98304 crc:0x13A763C8
2026-02-10 13:24:00,686 Serial: Streaming Data: len:4096 offset:102400 crc:0xCF840E31
2026-02-10 13:24:00,842 Serial: Streaming Data: len:4096 offset:106496 crc:0xF5BD7E3A
2026-02-10 13:24:00,999 Serial: Streaming Data: len:4096 offset:110592 crc:0x0D0F13DB
2026-02-10 13:24:01,156 Serial: Streaming Data: len:4096 offset:114688 crc:0x62ECFF6C
2026-02-10 13:24:01,313 Serial: Streaming Data: len:4096 offset:118784 crc:0xEFA83522
2026-02-10 13:24:01,470 Serial: Streaming Data: len:4096 offset:122880 crc:0xF1572503
2026-02-10 13:24:01,627 Serial: Streaming Data: len:4096 offset:126976 crc:0xC089E2F1
2026-02-10 13:24:01,784 Serial: Streaming Data: len:4096 offset:131072 crc:0x28EAEDDC
2026-02-10 13:24:01,941 Serial: Streaming Data: len:4096 offset:135168 crc:0x9C11C071
2026-02-10 13:24:02,098 Serial: Streaming Data: len:4096 offset:139264 crc:0xC2C3DB1B
2026-02-10 13:24:02,254 Serial: Streaming Data: len:4096 offset:143360 crc:0xF9F2ACD9
2026-02-10 13:24:02,411 Serial: Streaming Data: len:4096 offset:147456 crc:0x20E1CCAA
2026-02-10 13:24:02,567 Serial: Streaming Data: len:4096 offset:151552 crc:0x82CEF4E0
2026-02-10 13:24:02,724 Serial: Streaming Data: len:4096 offset:155648 crc:0x74D20EC2
2026-02-10 13:24:02,882 Serial: Streaming Data: len:4096 offset:159744 crc:0x093FA7C2
2026-02-10 13:24:03,039 Serial: Streaming Data: len:4096 offset:163840 crc:0x94E301F1
2026-02-10 13:24:03,196 Serial: Streaming Data: len:4096 offset:167936 crc:0x6A9153E6
2026-02-10 13:24:03,353 Serial: Streaming Data: len:4096 offset:172032 crc:0x5B16946A
2026-02-10 13:24:03,510 Serial: Streaming Data: len:4096 offset:176128 crc:0x79EF98EC
2026-02-10 13:24:03,667 Serial: Streaming Data: len:4096 offset:180224 crc:0x999C5E11
2026-02-10 13:24:03,824 Serial: Streaming Data: len:4096 offset:184320 crc:0x64AD589F
2026-02-10 13:24:03,987 Serial: Streaming Data: len:4096 offset:188416 crc:0x50B32268
Traceback (most recent call last):
  File "nordicsemi\dfu\dfu_transport_serial.py", line 123, in send_message
  File "serial\serialwin32.py", line 317, in write
serial.serialutil.SerialException: WriteFile failed (PermissionError(13, 'The device does not recognize the command.', None, 22))

During handling of the above exception, another exception occurred:

Traceback (most recent call last):
  File "nordicsemi\__main__.py", line 1545, in <module>
  File "click\core.py", line 1137, in __call__
  File "click\core.py", line 1062, in main
  File "click\core.py", line 1668, in invoke
  File "click\core.py", line 1668, in invoke
  File "click\core.py", line 1404, in invoke
  File "click\core.py", line 763, in invoke
  File "nordicsemi\__main__.py", line 1063, in serial
  File "nordicsemi\__main__.py", line 980, in do_serial
  File "nordicsemi\dfu\dfu.py", line 127, in dfu_send_images
  File "nordicsemi\dfu\dfu.py", line 100, in _dfu_send_image
  File "nordicsemi\dfu\dfu_transport_serial.py", line 301, in send_firmware
  File "nordicsemi\dfu\dfu_transport_serial.py", line 466, in __stream_data
  File "nordicsemi\dfu\dfu_transport_serial.py", line 125, in send_message
pc_ble_driver_py.exceptions.NordicSemiException: Writing to serial port failed: WriteFile failed (PermissionError(13, 'The device does not recognize the command.', None, 22)). If MSD is enabled on the target device, try to disable it ref. https://wiki.segger.com/index.php?title=J-Link-OB_SAM3U
[52512] Failed to execute script '__main__' due to unhandled exception!
CompletedProcess(args=['C:\\Users\\carlosgalindo\\AppData\\Local\\Arduino15\\packages\\rak_rui\\tools\\pc-nrfutil\\v6.1.7/nrfutil', '-v', '-v', '-v', 'dfu', 'serial', '--package', 'C:\\Users\\carlosgalindo\\workspaces\\Arduino\\mbox24-rak4630-lorawan/build/mbox24-rak4630-lorawan.ino.zip', '-p', 'COM6', '-b', '115200'], returncode=1)

Just thinking out loud here…

  1. do you see the same behavior using adafruit-nrfutil as you do with nrfutil? I know they get picky verifying the bootloader. I have an issue now where I can upload a arduino IDE generated .hex file with nrfutil but not with adafruit-nrfutil. Worth a test.
  2. Im not sure that MSD is that could be disabled on the device. In my shallow dig I didnt see it. The SEGGER wiki link is broken so you may need to do a deeper search.
  3. also, is it possible to JLINK to the SWD pins on the core board?

Thank you for your reply. I’ve since found a solution — it was related to the firmware, not the update tools.

At some point during development, I enabled the watchdog because the devices can occasionally get stuck. It doesn’t happen very often, but I needed a backup solution for these rare cases.

I was using the same configuration as shown in the documentation:

void setup() {
  api.system.wdt.enable(8000); // 8 seconds
}

void loop() {
  api.system.wdt.reset();
  ...
}

I’m not sure why, but it seems the watchdog is also enabled in boot mode and is not being reset. As a result, the upload process crashes at around 60%. This doesn’t happen — or at least not nearly as often — when using the IDE.

If I don’t enable the watchdog in the code, the update process works normally. That’s a bit frustrating, since I may need to use it, and the documentation states that it cannot be disabled until reboot, nor can it be increased beyond 8 seconds.

Glad you found it. It also looks like the WDT will disable on a power cycle.