iPadOS-specific Nordic DFU startup failure at 0% after `initialising`, same peripheral succeeds on another iPad

Hi,

We are investigating a Nordic BLE DFU startup failure on iPadOS and would appreciate guidance on whether this pattern is known at the CoreBluetooth / iOS DFU layer.

### Observed behavior

- Our iOS app starts DFU successfully and receives the `initialising` callback.
- The update then fails at `0%` after about 14 seconds.
- We do **not** receive any progress callback above 0%.
- We do **not** see a later reconnect/bootloader phase in this failing case.
- Right before failure, our app’s connected-device topology drops from the target peripheral to `none`.
- The same physical peripheral updates successfully on a different iPad.

### Comparison

Failing device:
- iPad 11th gen / `iPad15,7`
- iPadOS `26.4`
- App version `2.10.10`

Working device:
- iPad mini 4
- Same firmware package
- Same peripheral updates successfully

### Conditions already ruled out

- Only one BLE peripheral connected
- App kept in foreground
- Peripheral kept very close to iPad
- Rebooted iPad
- Toggled Bluetooth off/on
- Force-closed and reopened app

### Additional app-side check already performed

Our first detailed log showed metadata callbacks arriving for the target device during active DFU, and at that time our UI layer was still issuing a `setColor(...)` write to the same device.

We treated that as a possible self-interference bug, removed those color writes, shipped a new build, and captured another failing run. The second run still failed in the exact same way:

- `initialising`
- no progress above 0%
- metadata callbacks still occur, but now explicitly **skip** color restore
- device topology later becomes `none`
- failure after ~14 seconds with `maxRetryCountReached`

So at this point we believe app-side color writes are **not** the root cause.

### Failing timeline summary

Both failing runs look like:

- preflight completes normally
- DFU start requested
- `initialising(type: application)`
- no progress callback above 0%
- no later reconnect/bootloader progression surfaced by the SDK
- after ~14 seconds, topology drops to `none`
- terminal error surfaced by our layer as `FirmwareUpdateError.maxRetryCountReached`

### Raw excerpts

Run 1 (before removing metadata-triggered color writes):

```text
[2026-04-06T20:36:11.311Z] state=initialising(type: CosmoSDK.FirmwareUpdateType.application)
[2026-04-06T20:36:14.995Z] metadata arrived during active update — restoring its color only
[2026-04-06T20:36:26.084Z] state=failed(type: CosmoSDK.FirmwareUpdateType.application, error: CosmoSDK.FirmwareUpdateError.maxRetryCountReached)
```

Run 2 (after removing those color writes):

```text
[2026-04-09T01:31:12.905Z] state=initialising(type: CosmoSDK.FirmwareUpdateType.application)
[2026-04-09T01:31:16.497Z] Metadata arrived for updating device ... — skip color restore during DFU
[2026-04-09T01:31:27.557Z] state=failed(type: CosmoSDK.FirmwareUpdateType.application, error: CosmoSDK.FirmwareUpdateError.maxRetryCountReached)
```

### Question

Does this pattern match any known iPadOS / CoreBluetooth / Nordic DFU issue where:

1. DFU reaches `initialising`
2. transfer never starts beyond 0%
3. the peripheral disappears from the app topology after ~14 seconds
4. the session ends with `maxRetryCountReached`
5. the same peripheral succeeds on a different iPad

If so, are there recommended mitigations on iOS such as:

- different startup retry timing
- packet receipt notification settings
- reconnect handling adjustments
- MTU / PRN / bootloader handoff expectations
- known issues on newer iPad hardware / iPadOS releases

Thanks.
  • [10:40:59.731] Normal: Read Response received from 00001534-1212-EFDE-1523-785FEABCD123, value (0x): 0200
    [10:40:59.731] Normal: Version number read: 0.2

    Here you can see that the DFU revision characteristic returns v0.8 instead of v0.2 when the device is presumably in DFU mode. I suggest to debug the dfu target if possible to see why it may be failing to enter dfu mode.

Related