Crash in scan_bitmap_to_channel_list during Matter BLE commissioning on ESP32-C3 with external antenna

Author: florindCreated Feb 27, 2026Updated Sep 12, 2026
LabelsArea: Matter

Crash in scan_bitmap_to_channel_list during Matter BLE commissioning on ESP32-C3

Environment

  • Chip: ESP32-C3 with external u.FL antenna
  • Framework: Arduino ESP32 core 3.3.6 (also tested 3.3.5 and 3.3.7 — same crash)
  • IDF version: (bundled with Arduino core 3.3.6)
  • Board: ESP32-C3 Dev Module, 4MB flash, 160MHz
  • OS: macOS and Linux (crash reproduces on both)

Bug description

scan_bitmap_to_channel_list() in the WiFi driver (libnet80211.a) crashes with a load access fault during Matter BLE commissioning on ESP32-C3. The crash occurs deterministically at the same instruction address across multiple runs and configurations. It happens after the device receives WiFi credentials via BLE from the Matter controller (IKEA Dirigera) and the WiFi driver begins scanning for the target SSID.

Suspected trigger

The crash began occurring after attaching a high-gain external antenna (u.FL). Previously, the u.FL connector had no antenna attached (0-ohm resistor selects u.FL path, not chip antenna), resulting in very weak reception and few visible APs. With the external antenna, the device can see significantly more access points.

Analysis: 5GHz channel bitmap on a 2.4GHz-only chip

Disassembly of scan_bitmap_to_channel_list shows two loops:

  1. Bits 1-14: processes 2.4GHz channels — writes channel numbers directly
  2. Bits for 5GHz channels: maps bit positions to channel numbers 36, 40, 44, ... using offsets (+32, +33)

The crash at 0x42112d8a is in the 5GHz channel processing loop. The ESP32-C3 is a 2.4GHz-only chip (Wi-Fi 4, 802.11 b/g/n, 2.4 GHz per Espressif's datasheet).

Hypothesis: The Matter commissioning controller (IKEA Dirigera) provisions WiFi credentials that include 5GHz channel information (the target AP is dual-band). When these 5GHz channel bits are passed to scan_bitmap_to_channel_list, the function attempts to process them, but the 5GHz scan context (a structure accessed at offset 0x2C) is NULL because the C3 never initializes 5GHz radio structures.

This would explain:

  • Why it only crashes with the external antenna: stronger reception → Dirigera detects the router's 5GHz band → includes 5GHz channel info in provisioning
  • Why it only crashes during Matter commissioning: normal WiFi.scanNetworks() only uses 2.4GHz channels on the C3, so the 5GHz code path is never hit
  • Why the same firmware worked before: bare u.FL connector = too weak signal, Dirigera may not have detected 5GHz or followed a different provisioning path
  • Why it's not reported by others: most ESP32-C3 users either don't use Matter, or use the chip antenna (weaker signal, 5GHz less likely to be included)

Crash details

The crash is 100% reproducible across:

  • Multiple Arduino ESP32 core versions (3.3.5, 3.3.6, 3.3.7)
  • Multiple host computers (Mac and Linux)
  • Multiple firmware versions (including older commits where commissioning previously worked)
  • Full flash erases between attempts
  • Various CHIP_CONFIG_PACKET_BUFFER_POOL_SIZE values (6 and 10)

Register dump (most recent, with healthy heap)

[EVT] 0xC000  free=12496  block=7156  min=9052
Guru Meditation Error: Core  0 panic'ed (Load access fault). Exception was unhandled.

Core  0 register dump:
MEPC    : 0x42112d8a  RA      : 0x42112d78  SP      : 0x3fcbc930  GP      : 0x3fc96000
TP      : 0x3fcbca90  T0      : 0x4005890e  T1      : 0x4215669c  T2      : 0x0000db00
S0/FP   : 0x3fca8a80  S1      : 0x3fca8e14  A0      : 0x00000000  A1      : 0x00000040
A2      : 0x00000002  A3      : 0x00000000  A4      : 0x3fcba7c0  A5      : 0x3fca8a84
A6      : 0x4211278a  A7      : 0x0000e009  S2      : 0x3fca8a89  S3      : 0x3fca8a88
S4      : 0x5000027c  S5      : 0x00000001  S6      : 0x3fcd6c70  S7      : 0x3fce0000
S8      : 0x3ff1b000  S9      : 0x3fce0000  S10     : 0x3fcdf934  S11     : 0x00000000
T3      : 0x0000000b  T4      : 0x3fcbc89d  T5      : 0x00000008  T6      : 0x00000005
MSTATUS : 0x00001881  MTVEC   : 0x40380001  MCAUSE  : 0x00000005  MTVAL   : 0x0000002c

Key values:

  • MCAUSE: 0x00000005 — Load access fault
  • MTVAL: 0x0000002c — Faulting address (NULL + 0x2C offset)
  • MEPC: 0x42112d8a — Crash instruction (consistent across ALL crashes)

Symbol resolution

$ riscv32-esp-elf-addr2line -f -C 0x42112d8a
scan_bitmap_to_channel_list

Confirmed by symbol table — the function spans 0x42112c3e to 0x42112db4:

42112c3e T scan_bitmap_to_channel_list
42112db4 T scan_set_desChan

All crash instances (same firmware, different heap configurations)

Run free heap largest block min ever MEPC
1 (pool=10, pages=8) 10,072 3,060 2,292 0x42112d8a
2 (pool=10, pages=4) 10,072 3,060 2,512 0x42112d8a
3 (pool=6, pages=4) 9,652 4,084 4,800 0x42112d8a
4 (pool=6, pages=4, no enclosure) 12,496 7,156 9,052 0x42112d8a

Run 4 proves this is not a heap exhaustion issue — 9KB minimum free heap, 7KB largest block.

Events before crash

E (54890) chip[DMG]: Fail to retrieve data ... clusterId: 0x0000_0046, attributeId: 0x0000_0006 err = 5c3
E (55003) chip[DMG]: Fail to retrieve data ... clusterId: 0x1349_FC00, attributeId: 0x0000_0001 err = 5c3
[EVT] 0xD007  free=18284  block=7412  min=12212
[EVT] 0xC000  free=12496  block=7156  min=9052
Guru Meditation Error: Core  0 panic'ed (Load access fault). Exception was unhandled.

The cluster errors (0x0046 = ICD Management, 0x1349_FC00 = vendor-specific) occur before commissioning begins and are likely unrelated. The crash happens during the WiFi scan phase after BLE credential exchange.

The crash happens during Matter commissioning — the device starts standalone, and commissioning is triggered by a button press which enables BLE advertising for Matter.

Steps to reproduce

  1. ESP32-C3 with external antenna (u.FL) in an environment with many visible WiFi APs
  2. Flash a Matter-enabled Arduino sketch using ESP32 Arduino core 3.3.6
  3. Start Matter BLE commissioning (device advertises over BLE)
  4. Use a Matter controller to commission the device
  5. After the controller sends WiFi credentials and the device begins WiFi scanning, it crashes

Expected behavior

WiFi scan completes successfully and device connects to the provisioned network.

Actual behavior

Device crashes in scan_bitmap_to_channel_list with a NULL pointer dereference (load from address 0x2C) every time, at the exact same instruction.

Disassembly of crash site

The 5GHz loop section where the crash occurs:

asm
42112d42:  li    a3,36           # first 5GHz channel number
42112d46:  li    a0,0
42112d48:  li    t3,7
42112d4a:  li    t4,1
42112d4c:  li    t5,11
42112d4e:  li    t6,28           # loop bound (28 5GHz channels)
42112d50:  j     42112da0        # enter loop
...
42112d7c:  addi  a1,a5,1         # increment count
42112d80:  add   a5,a5,t1        # advance pointer (t1 = g_scan->offset_76)
42112d82:  sb    a2,0(a5)        # store channel number
42112d86:  sll   a5,t4,a6        # build bit mask
42112d8a:  not   a5,a5           # ← MEPC (crash reported here)

t1 is loaded from g_scan->offset_76 at 0x42112d06. If the 5GHz scan context is not initialized on the C3, this pointer or a derived structure could be NULL, leading to the access fault at offset 0x2C.

Confirmed workaround

Removing the external antenna before commissioning avoids the crash. The device commissions successfully with the bare u.FL connector (weak signal), and once commissioned, the external antenna can be reattached — the device reconnects to WiFi without going through scan_bitmap_to_channel_list.

This confirms the crash is triggered by the antenna improving reception during the WiFi scan phase of Matter commissioning.