Koenkk / Koenkk/zigbee2mqtt

Cannot use secret.yaml for MQTT credentials on add-on 2.13.0-1 — "mqtt must have required property 'server'"

Open
#32,832 0 comments 0 reactions 0 assignees View on GitHub

Nobody has claimed this yet.

problem
Dominant language
TypeScript
Stars
15.7k
Forks
2k
Avg merge
18h 55m
Merged PRs (30d)
35

Description

What happened?

Why are you guys not serious about security?

Environment
  • Zigbee2MQTT add-on 2.13.0-1 (latest, no update available)
  • Zigbee2MQTT core 2.13.0
  • Home Assistant Core 2026.8.1 / Home Assistant OS 18.2
  • data_path: /config/zigbee2mqtt
  • MQTT: Mosquitto add-on (mqtt://core-mosquitto:1883)
  • Adapter is network-attached (TubesZB CC2652 over Ethernet), not USB:
serial:
  port: socket://192.168.1.50:6638
  adapter: zstack
  baudrate: 115200
  rtscts: false
Goal

Keep the MQTT password out of configuration.yaml, so the file can be committed to a
private git repo. Followed the documented approach:
https://www.zigbee2mqtt.io/guide/configuration/mqtt.html

Attempt 1 — reference only in configuration.yaml

With the add-on stopped, created /config/zigbee2mqtt/secret.yaml:

password: <64-char password>

and set in configuration.yaml:

mqtt:
  base_topic: zigbee2mqtt
  server: mqtt://core-mosquitto:1883
  user: addons
  password: '!secret.yaml password'

Recorded md5sum configuration.yaml while stopped to prove the reference was on disk.
Started the add-on.

Result: Z2M started and connected fine, but configuration.yaml was rewritten — the
md5 changed and password: was back to the 64-char plaintext. secret.yaml was untouched.

This appears to be the add-on writing its own mqtt: options (which were mqtt: {}) into
configuration.yaml on start, per the discussion in Koenkk/zigbee2mqtt#27077.

Attempt 2 — reference in BOTH add-on options and configuration.yaml

Applied the workaround from that thread. Add-on options:

mqtt:
  server: "!secret.yaml mqtt_server"
  user: "!secret.yaml mqtt_user"
  password: "!secret.yaml mqtt_password"
  base_topic: zigbee2mqtt

/config/zigbee2mqtt/secret.yaml (mode 600, owned by root):

mqtt_server: mqtt://core-mosquitto:1883
mqtt_user: addons
mqtt_password: <64-char password>

configuration.yaml:

mqtt:
  base_topic: zigbee2mqtt
  server: '!secret.yaml mqtt_server'
  user: '!secret.yaml mqtt_user'
  password: '!secret.yaml mqtt_password'

Result: the references now persist in configuration.yaml (so that part of the
workaround does work), but Z2M refuses to start:

[16:44:03] INFO: Preparing to start...
[16:44:03] INFO: Socat not enabled
[16:44:03] INFO: Starting Zigbee2MQTT...
Starting Zigbee2MQTT without watchdog.
!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
            READ THIS CAREFULLY
Refusing to start because configuration is not valid, found the following errors:
- mqtt must have required property 'server'
If you don't know how to solve this, read https://www.zigbee2mqtt.io/guide/configuration
!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!

So the !secret.yaml references are not being resolved at all — the resulting config has
no mqtt.server.

Reverting both files to plaintext restores normal operation immediately.

Note

configuration.yaml also contains advanced.network_key in plain text, so this affects
more than the MQTT password for anyone version-controlling their config.

What did you expect to happen?

For the pass!secret.yaml <key> references in configuration.yaml should resolve at runtime from
<data_path>/secret.yaml, exactly as documented, so the MQTT password (and ideally
advanced.network_key) never appear as plaintext in configuration.yaml.

Instead, either the plaintext value is written back into the file, or the reference is
not resolved at all and Z2M refuses to start.word security to work

How to reproduce it (minimal and precise)
  1. Stop the Zigbee2MQTT add-on.
  2. Create /config/zigbee2mqtt/secret.yaml:
mqtt_server: mqtt://core-mosquitto:1883
mqtt_user: addons
mqtt_password: <password>
  1. In the add-on Configuration tab set:
mqtt:
  server: "!secret.yaml mqtt_server"
  user: "!secret.yaml mqtt_user"
  password: "!secret.yaml mqtt_password"
  base_topic: zigbee2mqtt
  1. In /config/zigbee2mqtt/configuration.yaml set the same three references.
  2. Start the add-on.

Result: refuses to start with mqtt must have required property 'server'.

Variant: with the references ONLY in configuration.yaml and mqtt: {} in the add-on
options, the add-on overwrites configuration.yaml on start and restores the plaintext
password. Verified by taking md5sum configuration.yaml while the add-on was stopped and
again after starting — the file changes.

Zigbee2MQTT version

2.13.0-1

Adapter firmware version

20211210

Adapter

CC2652

Setup

Home Assistant add-on (Supervisor), Home Assistant OS 18.2 running as a VM on Proxmox,
x86-64. Zigbee adapter is network-attached (TubesZB CC2652 over Ethernet, socket://),
not USB.

uname -a:
Linux 6.18.39-haos #1 SMP PREEMPT_DYNAMIC Thu Jul 30 12:31:10 UTC 2026 x86_64 Linux

/etc/issue.net: not applicable on Home Assistant OS (file does not exist)

Device database.db entry

Not attached — the failure occurs during config validation, before Z2M starts logging. The complete validation error is quoted in the body above.

Debug log

Not attached — the failure occurs during config validation, before Z2M starts logging.
The complete validation error is quoted in the body above.

Notes

This affects anyone version-controlling their Home Assistant configuration:
configuration.yaml contains both the MQTT password and advanced.network_key in
plaintext, and there appears to be no working way to externalise them on the add-on.

One untested theory for why the references silently fail to resolve: secret.yaml was
mode 0600 owned by root. If Z2M runs as a non-root user inside the add-on container it
may be unable to read it. configuration.yaml has the same owner and mode and is read
successfully, so this may be a red herring.

Happy to test a patch or provide further detail.

Contributor guide

Open the contributing guide

First steps

  1. Read the whole issue, then the project's contributing guide.
  2. Comment on the issue to say you are picking it up — it saves two people doing the same work.
  3. Fork the repository and make your change on a branch.
  4. Open a pull request that references the issue number.

Research direction

Start by reproducing the minimal configuration using configuration.yaml, the add-on options, and secret.yaml, then trace how add-on options are written and how !secret.yaml references reach configuration validation. Done means secret values resolve, mqtt.server passes validation, and starting the add-on no longer rewrites references as plaintext. Retest with the MQTT credentials and advanced.network_key cases described in the issue.

Written by the indexing model from the issue text.

Assessment

Tech stack
typescript
Domain
devops
Issue type
Bug
Difficulty
4/5
Estimated time
3-5 days
Activity status
Quiet
Clarity
Mostly clear
Newbie friendliness
45/100

Get new issues in your inbox

A short digest of beginner-friendly GitHub issues.