# Running Matter over Thread Alongside Zigbee in Home Assistant

> Setting up Thread without disrupting Zigbee

By Zsolt Bizderi · Published 2026-10-27
Canonical: https://ambientnode.uk/running-matter-over-thread-alongside-zigbee-in-home-assistant

Matter over Thread devices should be straightforward to add to Home Assistant. In practice, commissioning depends on several parts of the network working together. IPv6, multicast, Bluetooth and the Thread border router all need to be configured correctly, and the resulting error messages do not always identify the cause.

![image.png](/media/4b943797-a6e5-4234-ba75-8c8d01a6213f/864.webp)

This guide covers an SLZB-MR1 multiradio coordinator running Zigbee and Thread at the same time, with Home Assistant OS on a Proxmox VM and a UniFi network.

***

## What is needed

* An SLZB-MR1 or another Thread-capable radio. The SLZB-MR1 contains a Texas Instruments CC2652P7 and a Silicon Labs EFR32MG21, so the two protocols can use separate radios on the same device.
* Home Assistant OS, with the OpenThread Border Router and Matter Server add-ons.
* A Bluetooth adapter connected to the Home Assistant host for direct commissioning.
* IPv6 enabled on the LAN. A local Unique Local Address (ULA) prefix is sufficient. An IPv6 connection from the ISP is not required.
* A Matter over Thread device. Check the product specification before buying, because some smart home products use Zigbee or Matter over Wi-Fi instead.

***

## 1\. Identify and back up the Zigbee radio

Before flashing firmware, check which SLZB-MR1 radio is being used by Zigbee2MQTT. Flashing Thread firmware onto that chip erases its coordinator data and disconnects the Zigbee devices.

Check the Zigbee2MQTT configuration:

```
serial:
  port: tcp://10.10.1.185:6638
  adapter: ember
```

On the SLZB-MR1:

| Zigbee2MQTT adapter | Chip | Radio | Socket port |
| ------------------- | ---- | ----- | ----------- |
| `ember` or `ezsp` | Silicon Labs EFR32MG21 | Radio 1 | `6638` |
| `zstack` | Texas Instruments CC2652P7 | Radio 2 | `7638` |

Back up these files before changing firmware:

```
/config/zigbee2mqtt/coordinator_backup.json
/config/zigbee2mqtt/database.db
/config/zigbee2mqtt/configuration.yaml
```

The coordinator backup contains the network information needed to recover from a wiped coordinator. Without it, devices may need to be paired again.

***

## 2\. Assign the radios and update firmware

Open the SLZB-MR1 web dashboard and select **Settings and Tools > Firmware update**.

1. Update the coordinator's core firmware.
2. Flash Thread firmware to the radio not used by Zigbee2MQTT.
3. Under **Mode**, confirm that one radio is in Zigbee coordinator mode and the other is set to **Thread to remote OTBR**.

An example arrangement, where Zigbee already uses the Silicon Labs chip, is:

| Radio | Chip | Mode | Port | Baud rate |
| ----- | ---- | ---- | ---- | --------- |
| Radio 1 | EFR32MG21 | Zigbee coordinator | `6638` | `115200` |
| Radio 2 | CC2652P7 | Thread to remote OTBR | `7638` | `460800` |

For a new installation, the usual recommendation is Thread on the EFR32MG21 and Zigbee on the CC2652P7. Existing Zigbee networks should not be moved just to match that arrangement.

The SLZB-MR1 exposes the radio over TCP. If the connection drops, OTBR may not shut down cleanly and stale routes can remain temporarily. If Thread becomes unreliable, test with a direct USB connection where possible.

## 3\. Check IPv6 and multicast

Thread uses IPv6. The Proxmox host, Home Assistant OS, Docker and the LAN must all pass the required traffic.

### Proxmox

Check that IPv6 is enabled on the bridge and host:

```
sysctl net.ipv6.conf.vmbr0.disable_ipv6
sysctl net.ipv6.conf.all.disable_ipv6
```

Both should return `0`. If either returns `1`, enable IPv6 and make the setting persistent.

Check multicast snooping on the bridge:

```
cat /sys/class/net/vmbr0/bridge/multicast_snooping
```

If it returns `1`, test with snooping disabled:

```
echo 0 > /sys/class/net/vmbr0/bridge/multicast_snooping
```

To persist the change, add this to the `vmbr0` stanza in `/etc/network/interfaces`:

```
bridge-mcsnoop 0
```

### Home Assistant OS

From the Home Assistant VM console, run:

```
network info
```

The LAN interface should have a link-local IPv6 address beginning `fe80::`. A ULA address is also useful.

Check the IPv4 netmask. A `/32` can cause multicast socket binding failures. A typical LAN interface should use the correct subnet mask for the network, such as `/24` on a `10.10.1.0/24` network.

For that example network, the command would be:

```
network update enp0s18 --ipv4-method static --ipv4-address 10.10.1.107/24 --ipv4-gateway 10.10.1.1 --ipv4-nameserver 10.10.1.38
```

Adjust the interface name and addresses to match the installation.

### Docker IPv6

Home Assistant add-ons run in Docker containers. Check the Docker network configuration from the Home Assistant terminal:

```
ha docker info
```

If `enable_ipv6` is `null` or `false`, enable it:

```
ha docker options --enable-ipv6=true
```

Reboot Home Assistant, then run `ha docker info` again to verify the setting.

### UniFi

Check the following settings on the relevant network and wireless SSID:

* Enable IPv6 on the LAN and Router Advertisement (SLAAC). A ULA prefix such as `fd00:10:10:1::/64` is sufficient.
* Turn off **Multicast to Unicast** under **Hi-Capacity Tuning**.
* Disable IGMP snooping, or make sure the network's mDNS reflector is configured correctly.
* Turn off client or AP isolation.

Matter commissioning uses link-local multicast, which does not cross VLAN boundaries. For commissioning, put Home Assistant and the commissioning phone on the same network segment, or use direct Bluetooth commissioning from the Home Assistant host.

***

## 4\. Configure the OpenThread Border Router add\-on

Install the **OpenThread Border Router** and **Matter Server** add-ons.

Use the SLZB-MR1 Thread radio as the OTBR network device. For the example above, set:

| Setting | Value |
| ------- | ----- |
| Network Device | `10.10.1.185:7638` |
| Baud rate | `460800` |
| Hardware flow control | Off |
| Automatically flash firmware | Off |
| OTBR firewall | Off |
| NAT64 | Off |

The device field may require a placeholder such as `/dev/ttyS0` even when a network device is configured. If the Network Device field is missing from the visual editor, switch to YAML mode and add:

```
network_device: 10.10.1.185:7638
```

Do not leave **Automatically flash firmware** enabled if the radio has already been configured. The add-on could overwrite the radio firmware.

### Publish the OTBR ports

In the add-on's **Network** section, set the host ports for both services:

* OpenThread Web port: `8080`
* OpenThread REST API port: `8081`

The container ports may be shown on the right while the host port fields on the left are empty. If the host ports are empty, the REST API is not reachable from the LAN.

Save and restart the add-on. Check the API from another device on the network:

```
http://<ha-ip>:8081/node
```

It should return JSON. The following endpoints can also help verify the state:

```
http://<ha-ip>:8081/node/state
http://<ha-ip>:8081/node/dataset/active
```

Start OTBR and check its log. Look for `Role detached -> leader` and `Backbone Router becomes Primary!`. Errors such as `Failed to send RA` or `Failed to send RS` indicate that IPv6 routing or advertisements may not be working.

In Home Assistant, open **Settings > Devices & Services** and check that the OpenThread Border Router, Thread and Matter integrations appear. In the Thread panel, use the menu beside the border router and select **Add to preferred network**.

If the same border router appears twice, check for a stale configuration entry before commissioning devices.

## 5\. Plan the radio channels

Wi-Fi, Zigbee and Thread share the 2.4 GHz band. Wi-Fi channels are much wider than the 2 MHz 802.15.4 channels used by Zigbee and Thread.
If the Wi-Fi access points use channels 1, 6 and 11, 802.15.4 channels 25 and 26 are usually the least overlapped. A starting point is Thread on channel 26 and Zigbee on channel 25, but check the existing network and local interference before changing anything.

Set the Thread channel before adding devices. Changing it later can be more disruptive. The active Thread dataset can be checked at:

```
http://<ha-ip>:8081/node/dataset/active
```

If supported by the router, use 20 MHz rather than 40 MHz bandwidth for 2.4 GHz Wi-Fi.

***

## 6\. Commission the device directly over Bluetooth

Commissioning from the Home Assistant Companion app depends on the phone's Matter implementation and network position. Direct commissioning from the Matter Server avoids the phone's Thread credential store and network path, but requires a Bluetooth adapter accessible to the Matter Server.

### Enable Bluetooth in Matter Server

1. Open **Settings > Add-ons > Matter Server > Configuration**.
2. Enable **Show unused optional configuration options**.
3. Set **Bluetooth Adapter ID** to the correct adapter index, such as `0` for `hci0`.
4. Save and restart the add-on.

Find the adapter under **Settings > Devices & Services > Bluetooth**. If Home Assistant offers to add the Bluetooth integration for that adapter, the setup described here uses **Ignore** so the Matter Server can access it directly.

ESPHome Bluetooth proxies cannot carry out the commissioning connection. Disable them temporarily if they interfere with adapter selection.
Keep the device close to the Bluetooth adapter during commissioning. A USB extension cable can help if the Home Assistant host is in a rack.

### Get the Thread dataset and pairing code

Direct commissioning requires the Active Dataset TLV as a hexadecimal string, not JSON. From the Home Assistant terminal, run:

```
curl -H "Accept: text/plain" http://<ha-ip>:8081/node/dataset/active
```

The result should be a long hex string beginning with something like `0e08`. The Thread panel also exposes the dataset through the network information screen.

Use the device's manual pairing code or extract the `MT:` string from its QR code. For IKEA devices, the QR code and 11-digit code may be printed on the packaging or leaflet rather than on the device itself.

### Run commissioning

1. Open **Settings > Add-ons > Matter Server > Open Web UI**.
2. Select **Commission node > Commission new Thread device**.
3. Paste the Active Dataset TLV.
4. Enter the manual pairing code or `MT:` string.
5. Start the search, then power on the device.

Use **Commission new Thread device**, not **Commission new Wi-Fi device** or generic code entry through the Matter integration. The Thread-specific option accepts the dataset and passes the network credentials to the device.
The pairing window may expire after 15 minutes. If commissioning has taken too long, reset the device immediately before trying again.

***

## 7\. Verify commissioning

Check the Matter Server log for successful subscription and node registration. Typical lines include:

```
Subscription successful
PairedNode @1:a Endpoint structure needs to be updated
ThreadDetailsPoller Registered node @1:a for Thread topology polling
```

An IKEA device may then download a firmware update from the CSA Distributed Compliance Ledger. The appearance of an update is a useful sign that the device has reached the network and the update service.

***

## Matter over Thread or Zigbee?

For simple sensors and switches, the practical difference may be small. Matter and Thread support multi-admin, so a device can be shared across controllers such as Home Assistant, Apple Home and Google Home. Matter devices can also describe their supported capabilities without requiring a Zigbee2MQTT converter for each model.

Zigbee remains mature and has extensive tooling. Zigbee2MQTT provides a network map, link quality information, OTA management and MQTT integration. Home Assistant's Thread view currently provides less detail about the mesh.

Thread also has more dependencies. It needs a working border router, IPv6 routing, router advertisements and multicast. A Zigbee network can work normally while those parts of the IP network are misconfigured.

So why not both? Keep existing Zigbee devices on their current network and use Thread for devices that require it. The SLZB-MR1 can run both protocols using separate radios, provided the firmware and channels are configured correctly.
