$linuxjunkies
>

Install Zigbee2MQTT

Install Mosquitto, configure a Zigbee USB coordinator, run Zigbee2MQTT as a systemd service, and pair devices using the built-in web frontend.

IntermediateUbuntuDebianFedoraArch9 min readUpdated June 7, 2026

Before you start

  • A supported Zigbee USB coordinator (e.g. SONOFF Zigbee 3.0 USB Dongle Plus) plugged in
  • sudo or root access on the target Linux host
  • Internet access to download packages and clone the repository

Zigbee2MQTT bridges your Zigbee devices—sensors, bulbs, switches—to an MQTT broker, giving you local control without vendor clouds. It pairs naturally with Home Assistant, Node-RED, or any MQTT-capable automation platform. This guide covers the full stack: Mosquitto broker, coordinator adapter, the Zigbee2MQTT service, and the built-in web frontend.

Prerequisites and Hardware

You need a Zigbee USB coordinator—the most widely supported options are the SONOFF Zigbee 3.0 USB Dongle Plus (based on the CC2652P chip) and the SLZB-06 for Ethernet. Plug the coordinator in before starting and confirm the kernel sees it:

ls /dev/serial/by-id/

You should see a symlink like usb-ITead_Sonoff_Zigbee_3.0_USB_Dongle_Plus_.... Note the full path; you will use it in the Zigbee2MQTT config. If nothing appears, check dmesg | tail -20 for USB errors.

Step 1 – Install Mosquitto

Mosquitto is the de-facto MQTT broker for self-hosted setups. Install it from your distro's repositories.

Debian / Ubuntu

sudo apt update
sudo apt install -y mosquitto mosquitto-clients

Fedora / RHEL 9 / Rocky 9

sudo dnf install -y mosquitto

Arch

sudo pacman -S mosquitto

Enable and start the service:

sudo systemctl enable --now mosquitto

By default Mosquitto 2.x ships with a config that rejects anonymous connections. Create a password file for Zigbee2MQTT:

sudo mosquitto_passwd -c /etc/mosquitto/passwd zigbee2mqtt

Enter a password when prompted. Then create or edit /etc/mosquitto/conf.d/local.conf:

sudo tee /etc/mosquitto/conf.d/local.conf <<'EOF'
listener 1883 127.0.0.1
allow_anonymous false
password_file /etc/mosquitto/passwd
EOF

Binding to 127.0.0.1 keeps the broker off the network. If Home Assistant runs on a different host, change this to 0.0.0.0 and protect port 1883 at the firewall. Restart Mosquitto after any config change:

sudo systemctl restart mosquitto

Step 2 – Install Node.js

Zigbee2MQTT requires Node.js 18 or later. Avoid the distro-packaged version on older LTS releases—it is often too old.

Debian / Ubuntu (NodeSource)

curl -fsSL https://deb.nodesource.com/setup_20.x | sudo -E bash -
sudo apt install -y nodejs

Fedora / RHEL 9 / Rocky 9

sudo dnf module enable nodejs:20 -y
sudo dnf install -y nodejs npm

Arch

sudo pacman -S nodejs npm

Confirm the version:

node --version   # should print v20.x.x or later

Step 3 – Install Zigbee2MQTT

The project recommends installing from source via Git to stay close to upstream releases.

sudo mkdir -p /opt/zigbee2mqtt
sudo chown $USER:$USER /opt/zigbee2mqtt
git clone --depth 1 https://github.com/Koenkk/zigbee2mqtt.git /opt/zigbee2mqtt
cd /opt/zigbee2mqtt
npm ci

npm ci installs exact dependency versions from the lockfile. Expect it to take a few minutes the first time.

Step 4 – Configure Zigbee2MQTT

The configuration file lives at /opt/zigbee2mqtt/data/configuration.yaml. Copy the example and edit it:

cp /opt/zigbee2mqtt/data/configuration.yaml.example \
   /opt/zigbee2mqtt/data/configuration.yaml
nano /opt/zigbee2mqtt/data/configuration.yaml

A minimal working configuration looks like this. Replace the serial port path and MQTT password with your own values:

cat /opt/zigbee2mqtt/data/configuration.yaml
homeassistant: false

mqtt:
  base_topic: zigbee2mqtt
  server: mqtt://localhost
  user: zigbee2mqtt
  password: YOUR_MQTT_PASSWORD

serial:
  port: /dev/serial/by-id/usb-ITead_Sonoff_Zigbee_3.0_USB_Dongle_Plus_...

frontend:
  port: 8080

permit_join: false

Always use the /dev/serial/by-id/ path rather than /dev/ttyUSB0—the by-id symlink is stable across reboots; ttyUSBx numbers can shift if you add other USB devices.

Set homeassistant: true if you want automatic MQTT discovery in Home Assistant. Leave permit_join: false for now; you will flip it temporarily when pairing devices.

Step 5 – Create a systemd Service

Running Zigbee2MQTT as a systemd service gives you automatic restarts and journal logging. Create the unit file:

sudo tee /etc/systemd/system/zigbee2mqtt.service <<'EOF'
[Unit]
Description=Zigbee2MQTT
After=network.target mosquitto.service
Requires=mosquitto.service

[Service]
Type=notify
User=pi
WorkingDirectory=/opt/zigbee2mqtt
ExecStart=/usr/bin/node index.js
Restart=on-failure
RestartSec=10
WatchdogSec=60

[Install]
WantedBy=multi-user.target
EOF

Replace User=pi with your actual username. If you installed as root, you can use User=root, but running as an unprivileged user is strongly preferred. That user needs read/write access to the serial device:

sudo usermod -aG dialout $USER   # Debian/Ubuntu/Fedora
# On Arch the group is 'uucp':
# sudo usermod -aG uucp $USER

Log out and back in for the group to take effect, then enable the service:

sudo systemctl daemon-reload
sudo systemctl enable --now zigbee2mqtt

Step 6 – Verify the Service

Check the service is running and watch the initial logs:

sudo systemctl status zigbee2mqtt
journalctl -u zigbee2mqtt -f

Healthy output includes lines like Zigbee2MQTT started! and MQTT publish: topic 'zigbee2mqtt/bridge/state'. If it fails immediately, look for serial port permission errors or MQTT connection refused—both are common first-run problems covered in the troubleshooting section below.

Open the web frontend in a browser:

xdg-open http://localhost:8080   # or navigate manually on a remote host

Step 7 – Pair Zigbee Devices

Pairing (joining) is controlled by the permit_join setting. Enable it temporarily from the frontend or by editing the config and restarting. The safer method is the frontend: open Settings → Permit join and toggle it on. It auto-disables after 254 seconds by default.

With joining permitted, put your device into pairing mode (usually by holding the reset button until an LED flashes). The frontend Devices tab shows newly joined devices in real time. Once paired, disable joining again immediately to prevent unauthorized devices from joining.

You can also toggle joining from the command line using mosquitto_pub:

mosquitto_pub -h localhost -u zigbee2mqtt -P YOUR_MQTT_PASSWORD \
  -t zigbee2mqtt/bridge/request/permit_join \
  -m '{"value": true, "time": 120}'

Troubleshooting

Serial port access denied

If the journal shows Error: Permission denied, cannot open /dev/ttyUSB0, the service user is not in the dialout (or uucp on Arch) group, or the group change hasn't taken effect. Verify with:

groups $USER

If the group is missing, add it and log out completely (a new SSH session is not enough if the original login session is still open). As a temporary workaround you can set the service User=root, but fix the group properly before production use.

MQTT connection refused

Confirm Mosquitto is listening:

ss -tlnp | grep 1883

Then test authentication separately:

mosquitto_sub -h localhost -u zigbee2mqtt -P YOUR_MQTT_PASSWORD -t 'zigbee2mqtt/#' -v

A credentials mismatch gives Connection Refused: not authorised. Regenerate the password file entry with mosquitto_passwd and ensure the same password is in configuration.yaml.

Coordinator not detected

Some CC2652-based dongles require a firmware update to work reliably on Linux 6.x kernels with the cp210x driver. Check the Z-Stack firmware repository for the latest coordinator firmware and flash it using the vendor's flashing tool before troubleshooting further.

Keeping Zigbee2MQTT Updated

Pull the latest code and reinstall dependencies:

cd /opt/zigbee2mqtt
git pull
npm ci
sudo systemctl restart zigbee2mqtt
tested on:Ubuntu 24.04Debian 12Fedora 40Arch rolling

Frequently asked questions

Can I run Zigbee2MQTT without Home Assistant?
Yes. Zigbee2MQTT is fully standalone. Set homeassistant: false in configuration.yaml and integrate with any MQTT-capable platform such as Node-RED, OpenHAB, or a custom application.
My coordinator shows as /dev/ttyUSB0. Is that safe to use?
It works but is fragile—the number can change after a reboot if other USB serial devices are present. Always use the stable symlink under /dev/serial/by-id/ in your configuration.
How do I update Zigbee2MQTT?
Run git pull in /opt/zigbee2mqtt, then npm ci, and restart the service with systemctl restart zigbee2mqtt. Your paired device database in the data/ folder is preserved.
Does Zigbee2MQTT support Zigbee routers and mesh networking?
Yes. Mains-powered Zigbee devices (bulbs, plugs) act as routers and extend the mesh automatically. Battery-powered end devices connect through the nearest router or directly to the coordinator.
The coordinator needs a firmware update. How do I flash it?
For CC2652-based dongles use the Texas Instruments Flash Programmer 2 on Windows, or the open-source cc2538-bsl Python tool on Linux. Download the latest coordinator firmware from the Koenkk/Z-Stack-firmware GitHub repository.

Related guides