# \[Bug\] NullPointerException in BondStateMachine.isSkipConfirmationAccessory crashes Bluetooth when pairing a device with no name (LOS21 / iodéOS 5.25)

**URL:** <https://community.iode.tech/t/bug-nullpointerexception-in-bondstatemachine-isskipconfirmationaccessory-crashes-bluetooth-when-pairing-a-device-with-no-name-los21-iodeos-5-25/8755>\
**Category:** System and Apps\
**Created:** [28 September 2026 04:40 UTC](https://community.iode.tech/t/bug-nullpointerexception-in-bondstatemachine-isskipconfirmationaccessory-crashes-bluetooth-when-pairing-a-device-with-no-name-los21-iodeos-5-25/8755 "2026-09-28T04:40:08Z")\
**Posts on this page:** 4\
**Page:** 1

<div class="post-metadata">

**Author:** ![hans1969](https://community.iode.tech/letter_avatar_proxy/v4/letter/h/9fc348/32.png) [@hans1969](https://community.iode.tech/u/hans1969)\
**Post date:** [28 September 2026 04:40 UTC](https://community.iode.tech/t/bug-nullpointerexception-in-bondstatemachine-isskipconfirmationaccessory-crashes-bluetooth-when-pairing-a-device-with-no-name-los21-iodeos-5-25/8755/1 "2026-09-28T04:40:08Z")

</div>

**Environment**

- ROM: iodeOS 5.25 (LineageOS 21 base), Android 14
- 
  - Device: Samsung Galaxy S20, iodeOS GSI (lineage\_arm64\_ab / tdgsi\_arm64\_ab)
  - 
    - Build flavor: lineage\_arm64\_ab-userdebug
    - 
      - Security patch: 2026-06-01

    - **Summary**
    - Pairing a Bluetooth device that does not advertise a name at bond time (e.g. Garmin fenix) crashes the com.android.bluetooth process. The bond never completes and I have to re-pair the device several times a day.

  - **Root cause**
  - BondStateMachine.isSkipConfirmationAccessory() calls .equals() on the remote device name without a null check. When getName() returns null, this throws an NPE and the Bluetooth stack dies. This method is LineageOS-specific (introduced in change 382143, “BondStateMachine: Allow skipping confirm for some remotes”), so it is not an AOSP bug.

- **Stack trace (from device, Android 14 / LOS21)**
- `java.lang.NullPointerException: ‘boolean java.lang.Object.equals(java.lang.Object)’ on a null object reference`
- 
  - at BondStateMachine.isSkipConfirmationAccessory(BondStateMachine.java:471)
  - 
    - at BondStateMachine.sendDisplayPinIntent(BondStateMachine.java:483)
    - 
      - at BondStateMachine$PendingCommandState.processMessage(BondStateMachine.java:344)

    - **Steps to reproduce**
    - 
      1. Use a BT device that initially exposes no name during bonding (Garmin fenix).
      2. 
        1. Initiate pairing.
        2. 
          1. com.android.bluetooth crashes and the bond fails.

        3. **Workaround (confirms the root cause)**
        4. Scanning for the device in the Bluetooth settings first (so its name gets cached and getName() is no longer null) avoids the crash.

      3. **Suggested fix**
      4. Add a null guard before the name comparison in isSkipConfirmationAccessory() (e.g. if (name != null && name.equals(…))). This is already fixed in the lineage-22.x branch - please cherry-pick / backport the existing fix to lineage-21.0, since LOS21 devices are still widely used.

---

<div class="post-metadata">

**Author:** ![hans1969](https://community.iode.tech/letter_avatar_proxy/v4/letter/h/9fc348/32.png) [@hans1969](https://community.iode.tech/u/hans1969)\
**Post date:** [28 September 2026 05:04 UTC](https://community.iode.tech/t/bug-nullpointerexception-in-bondstatemachine-isskipconfirmationaccessory-crashes-bluetooth-when-pairing-a-device-with-no-name-los21-iodeos-5-25/8755/2 "2026-09-28T05:04:39Z")

</div>

I compared the buggy lineage-21.0 code with the fixed lineage-22.1 and prepared a ready-to-apply backport patch, in case it helps the team push it upstream via Gerrit.

File: android/app/src/com/android/bluetooth/btservice/BondStateMachine.java

````auto
diff
--- a/android/app/src/com/android/bluetooth/btservice/BondStateMachine.java
+++ b/android/app/src/com/android/bluetooth/btservice/BondStateMachine.java
@@ -469,7 +469,11 @@
     private boolean isSkipConfirmationAccessory(BluetoothDevice device) {
         for (Pair<String, Integer> entry : accConfirmSkip) {
- if (device.getName().equals(entry.first)
+ String name = device.getName();
+ if (name == null) {
+ return false;
+ }
+ if (name.equals(entry.first)
                     && device.getBluetoothClass().getDeviceClass() == entry.second) {
                 return true;
             }
         }
```

Suggested commit message:

```
BondStateMachine: Guard against null device name in isSkipConfirmationAccessory

device.getName() can return null (e.g. when a peer initiates bonding before its name is resolved, such as a Garmin fenix). Calling .equals() on it throws a NullPointerException that crashes com.android.bluetooth and prevents the bond from completing.

Backport of the null guard already present on lineage-22.x.
```

This is a direct backport of the guard that already exists on lineage-22.1 (there the same method wraps the name in a `if (name == null) return false;` check before calling .equals()).

````

---

<div class="post-metadata">

**Author:** ![rik](https://community.iode.tech/user_avatar/community.iode.tech/rik/32/1437_2.png) [@rik](https://community.iode.tech/u/rik)\
**Post date:** [28 September 2026 16:38 UTC](https://community.iode.tech/t/bug-nullpointerexception-in-bondstatemachine-isskipconfirmationaccessory-crashes-bluetooth-when-pairing-a-device-with-no-name-los21-iodeos-5-25/8755/3 "2026-09-28T16:38:58Z")

</div>

I think you will have much better luck with a custom build rather than the GSI. User @ronnz98 makes iodéOS 7.x / Android 16 builds for this device, currently I think their most recent builds are `7.5` which is a few months back:

> [@Unofficial builds for the Samsung S20 Exynos series (S20, S20 FE, S20+, S20 Ultra) for iode 7.x](https://community.iode.tech/t/unofficial-builds-for-the-samsung-s20-exynos-series-s20-s20-fe-s20-s20-ultra-for-iode-7-x/7454):
>
> Samsung Galaxy S20 series for iode 7.x First Android 16 / LOS23 based builds for the S20 series. Samsung Galaxy S20 5G (x1s) [iode-7.1-20251226-x1s.zip](https://sourceforge.net/projects/eosbuildsronnz98/files/OtherCustomROMS/iode/iode-7.1-20251226-x1s.zip/download "Click to download iode-7.1-20251226-x1s.zip") Samsung Galaxy S20 Plus (y2s) [iode-7.1-20251226-y2s.zip](https://sourceforge.net/projects/eosbuildsronnz98/files/OtherCustomROMS/iode/iode-7.1-20251226-y2s.zip/download "Click to download iode-7.1-20251226-y2s.zip") Samsung Galaxy S20 Ultra (z3s) [iode-7.1-20251226-z3s.zip](https://sourceforge.net/projects/eosbuildsronnz98/files/OtherCustomROMS/iode/iode-7.1-20251226-z3s.zip/download "Click to download iode-7.1-20251226-z3s.zip") Samsung Galaxy S20 FE (r8s) Exnyos [iode-7.1-20251226-r8s.zip](https://sourceforge.net/projects/eosbuildsronnz98/files/OtherCustomROMS/iode/iode-7.1-20251226-r8s.zip/download "Click to download iode-7.1-20251226-r8s.zip") Please see sources and install instructions including recovery here: These devices are now officially supported for LOS23! Use it at your own risk! Please…

---

<div class="post-metadata">

**Author:** ![hans1969](https://community.iode.tech/letter_avatar_proxy/v4/letter/h/9fc348/32.png) [@hans1969](https://community.iode.tech/u/hans1969)\
**Post date:** [29 September 2026 15:18 UTC](https://community.iode.tech/t/bug-nullpointerexception-in-bondstatemachine-isskipconfirmationaccessory-crashes-bluetooth-when-pairing-a-device-with-no-name-los21-iodeos-5-25/8755/4 "2026-09-29T15:18:30Z")

</div>

Thanks! That really helps!
