Issue
BluetoothLowEnergy.CONNECTION_STRATEGY_SECURE_PAIR_BOND followed by BluetoothLowEnergy.pairDevice() reproducibly causes a native watch restart while connecting to a PIN-disabled Meshtastic BLE peripheral.
I reduced this to a standalone app with only the BluetoothLowEnergy permission. It contains no production UI, storage, protobuf parsing, Sensor API integration, timers, communications permission, or third-party barrel.
The default-strategy control connects successfully. An otherwise identical build that selects CONNECTION_STRATEGY_SECURE_PAIR_BOND restarts the entire watch before the connected callback is delivered.
Environment
- Device: Garmin Venu 3S
- Part number: 006-B4261-00
- Firmware: 17.05
- Connect IQ version: 6.0
- Connect IQ SDK: 9.2.0
- Build OS: Ubuntu 24.04
- Development tool:
monkeyccommand line - VS Code and extension: Not applicable
- App type: Watch app
- Manifest minimum API: 5.1.0
- Peripheral: Meshtastic BLE radio with PIN disabled
- Peripheral service UUID:
6ba1b218-15a8-461f-9fa8-5dcae273eafd
Minimal Application Behaviour
The standalone application:
- Registers the Meshtastic BLE service and its three characteristics.
- Scans for advertisements containing the service UUID.
- Uses a fresh
ScanResultreceived byonScanResults(). - Stops scanning before pairing.
- Retains the fresh
ScanResult. - Retains the
Devicereturned bypairDevice(). - Waits for
onConnectedStateChanged(). - Performs no characteristic or descriptor I/O.
This follows the object-lifetime pattern used by Garmin's NordicThingy52 sample and rules out stale ScanResult or prematurely collected Device objects.
Controlled A/B Result
I built two variants from the same source. Their only behavioural difference is the selected connection strategy.
Default-Strategy Control
The default-strategy build connects successfully:
REPRO: app-start used=8760 free=773232 total=781992
REPRO: connection-strategy=default
REPRO: profile-registered-call-returned
REPRO: scan-started
REPRO: match name=null rssi=-49
REPRO: scan-stop-call-returned
REPRO: pairDevice-returned device=non-null
REPRO: connected-state=1 isConnected=true
REPRO: app-stop
The control produced no new native error or watch restart. This rules out a general pairDevice() failure on this device and firmware.
Secure-Strategy Variant
The secure build changes only one behaviour. Before registering the profile and starting the scan, it calls:
BluetoothLowEnergy.setConnectionStrategy(
BluetoothLowEnergy.CONNECTION_STRATEGY_SECURE_PAIR_BOND
);
The application finds the same peripheral, stops scanning, retains the fresh ScanResult, and retains the non-null Device returned by pairDevice(). The entire watch then restarts before onConnectedStateChanged(CONNECTION_STATE_CONNECTED) is delivered.
Reproduction Steps
- Configure a Meshtastic radio with Bluetooth enabled and pairing mode set to No PIN.
- Disconnect any phone or other BLE central from the radio.
- Place the radio within one metre of the Venu 3S.
- Install and launch the attached secure BLE Pair Repro watch app.
- The app discovers the service, stops scanning, and calls
pairDevice(). pairDevice()returns a non-nullDevice.- The entire watch restarts before the connected-state callback is delivered.
Native Error
error_cause: RTL Trap
RTL Error Number: 0x037
program counter: 0x10001491
page stack depth: 3
page stack: 1028,1127,1030
The secure application's pre-created Connect IQ log remains empty because the firmware restarts before its output is flushed. A redacted Garmin native error record is attached.
Available memory immediately before BLE setup is approximately 773 KB, so this is not a Connect IQ out-of-memory exception.
Expected Behaviour
The secure strategy should establish the secure connection, report a failure through a documented exception or BLE callback/status, or report that the requested strategy is unsupported.
Calling a public Connect IQ API must not cause a native RTL trap and restart the entire watch.
Attachments
venu3s-pairdevice-repro-source.zip: complete minimal source for both default and secure variants, excluding generated binaries.default-control-success.txt: complete successful control trace.secure-strategy-native-error-redacted.txt: native Venu 3S error record with the unique unit ID removed.
I can provide the complete native error record and Garmin-generated RAM dump through a private channel if required. I have not attached the RAM dump publicly because it may contain device-identifying or runtime data.
Related Reports
- vívoactive 5 pairDevice() not working anymore
- BLE bug in Venu 3 and vívoactive 5 firmware
- BLE-related device crash
venu3s-pairdevice-repro-source.zip
REPRO: app-start used=8760 free=773232 total=781992 REPRO: connection-strategy=default REPRO: profile-registered-call-returned REPRO: scan-started REPRO: match name=null rssi=-49 REPRO: scan-stop-call-returned REPRO: pairDevice-returned device=non-null REPRO: connected-state=1 isConnected=true REPRO: app-stop
[
{
"unit_id": "REDACTED",
"product_name": "Venu 3S",
"software_part_number": "006-B4261-00",
"ms_since_epoch": "1783960840000",
"system_version": "17.05",
"build_type": "Production",
"backtrace": "0x100013f1\n\t0x1000116b\n\t0x10009fcd\n\t0x181fce73\n\t0x100010e1\n\t0x10000003\n\t0x1000000f\n\t0x1000000f\n\t0x1000000f\n\t0x1000000f\n\t0x1000000f\n\t0x1000000f\n\t0x1000000f\n\t0x1000000f\n\t0x1000000f\n\t0x1000000f\n\t0x1000000f\n\t0x1000000f\n\t0x1000000f\n\t0x1000000f\n\t0x1000000f\n\t0x1000000f\n\t0x10000007\n\t0x10000003\n\t0x1000000f\n\t0x1000000f\n\t0x1000000f\n\t0x1000000f\n\t0x1000000f\n\t0x1000000f\n\t0x1000000f\n\t0x1000000f\n\t",
"error_cause": "RTL Trap",
"proprietary_info": {
"Commit ID": "03cc5699e48b7e90c6414fcc4ec45cdd70cfd780",
"Time": "2026-7-13 16:40:40",
"uptime": "63078085",
"pageStackDepth": "3",
"pageStack": "1028,1127,1030",
"RTL Error Number": "0x037",
"rtl_reg": "r[0]: 0x303223f1\n\tr[1]: 0x30322734\n\tr[2]: 0x00000001\n\tr[3]: 0x00000000\n\tr[4]: 0x303223f1\n\tr[5]: 0x00000001\n\tr[6]: 0x00000001\n\tr[7]: 0x30322378\n\tr[8]: 0x00000001\n\tr[9]: 0x3033897c\n\tr[10]: 0x304a9320\n\tr[11]: 0x000000ff\n\tr[12]: 0x10009fcd\n\tr[13]: 0x30322358\n\tr[14]: 0x181fce73\n\tr[15]: 0x00000000\n\tr[16]: 0x60100000\n\tr[17]: 0x00000000\n\tr[18]: 0x00020000\n\tr[19]: 0xe000ed38\n\tr[20]: 0xe000ed34\n\tr[21]: 0x00000000\n\tr[22]: 0x303222f0\n\t",
"programCounter": "0x10001491",
"stackPointer": "0x303ae9b8"
}
}
]