Devices fail to rejoin after coordinator migration
Nobody has claimed this yet.
- Dominant language
- TypeScript
- Stars
- 15.7k
- Forks
- 2k
- Avg merge
- 18h 55m
- Merged PRs (30d)
- 35
Description
What happened?
TypeError: Cannot read properties of undefined (reading 'save') during bind/configure, DatabaseEntry never persists
After migrating my Zigbee network from one Ember-based coordinator (SMLIGHT SLZB-MR2, EFR32MG21) to another (Sonoff ZBDongle-E, also EFR32/Ember) by restoring the coordinator_backup.json, most of my 100+ devices reconnected without re-pairing, as expected — the IEEE address of the coordinator was preserved by the backup restore process.
However, a subset of devices that were disconnected during a power outage after the migration are now completely unable to rejoin the network. Every pairing attempt fails consistently with the same error, and — critically — the device is never persisted to database.db, even when the interview itself appears to fully succeed (Successfully interviewed, Successfully configured in logs), leaving no trace of the device anywhere in Zigbee2MQTT's state.
This has happened to me on 4 separate previously-working devices (3x Tuya TS011F smart plugs, 1x SONOFF SNZB-02D temp/humidity sensor) since the migration. Two of them (a smart plug and the temp sensor) were lost during a successful-looking pairing attempt — the logs showed Successfully configured, yet the device vanished from database.db and never appeared in the frontend.
To Reproduce
Start with a stable Zigbee2MQTT network using an Ember-based coordinator (EmberZNet, EZSP)
Migrate to a new physical Ember coordinator by restoring coordinator_backup.json (same PAN ID, same coordinator IEEE address preserved via zigpy/open-coordinator-backup format)
Confirm the new coordinator is fully operational — dozens/hundreds of devices reconnect and function normally
Have one or more devices leave the network (in my case: a power outage disconnected several Zigbee mains-powered routers)
Attempt to re-pair the disconnected device (Permit Join → physical pairing button on device)
Observe interview repeatedly fails with DatabaseEntry with ID 'X' does not exist, or in some cases succeeds and is logged as Successfully configured but the device still does not persist
What did you expect to happen?
The device should either:
Successfully rejoin and persist to database.db (interview + configure completing cleanly), or
Fail consistently and predictably without silently corrupting/dropping the device from the database after an apparently successful interview
Disk space / filesystem issues: the LXC container hosting Zigbee2MQTT was found to have its EXT4 filesystem at 96% capacity with active journal errors (ext4_journal_check_start). I fixed this (fsck + resize2fs to expand the volume, confirmed 58% usage afterward with no further fs errors), but the exact same error persists identically afterward.
state.json residue: found one affected device (0x38398ffffede01e6) had a stale empty entry ("0x38398ffffede01e6": {}) in state.json. This entry disappeared on its own after a container/service restart, but the pairing failure persisted identically regardless.
Coordinator database entry corruption: verified only one "type":"Coordinator" entry exists in database.db, matching the correct IEEE address, no duplicates.
Z2M version: issue persists identically across an update from 2.12.0 → 2.12.1 (zigbee-herdsman 10.4.0 → 10.6.1, zigbee-herdsman-converters 26.63.0 → 26.76.0).
Full container restart: issue persists after a complete pct stop/pct start of the LXC (not just a service restart), ruling out any leftover process memory state.
How to reproduce it (minimal and precise)
No response
Zigbee2MQTT version
Zigbee2MQTT: 2.12.0 → 2.12.1 (both affected) zigbee-herdsman: 10.4.0 → 10.6.1 (both affected) zigbee-herdsman-converters: 26.63.0 → 26.76.0 (both affected)
Adapter firmware version
Revisión: 7.4.4 [GA]
Adapter
Sonoff ZBDongle-E (EFR32MG21, EmberZNet/EZSP, firmware 7.4.4 [GA]) Adapter config: adapter: ember, connected via USB passthrough to a Debian LXC container (Proxmox) Coordinator was migrated from a SMLIGHT SLZB-MR2 (also EFR32/Ember) via coordinator_backup.json restore (zigpy/open-coordinator-backup format, version 1)
Setup
~105 devices total on the network, mix of Tuya TS011F plugs, SONOFF SNZB sensors, Innr/LEDVANCE bulbs, Aqara contact sensors
Affected devices (all previously working for months/years, all Tuya _TZ3000 TS011F plugs except the temp sensor):
0x70b3d52b6007cc23 (TS011F_plug_3)
0x70b3d52b60060aa4 (TS011F_plug_3)
0x70b3d52b6005865f (TS011F_plug_3)
0x38398ffffede01e6 (SONOFF SNZB-02D)
I'm happy to provide the full database.db (redacted) or additional debug-level logs if useful. I still have all four physical devices available for further testing/reproduction if a maintainer wants me to try something specific before I attempt any further manual database edits.
Device database.db entry
No response
Debug log
Observed error (repeated across multiple devices and multiple attempts)
[date] zh:controller: Interview for '0x70b3d52b6007cc23' started
[date] z2m: Device 'Homelab ventilador' joined
[date] z2m: Starting interview of 'Homelab ventilador'
[date] z2m: Device 'Homelab ventilador' left the network
[date] zh:controller:endpoint: Tried to get unknown/deleted device 0x70b3d52b6007cc23 from endpoint 1.
[date] zh:controller: Interview failed for '0x70b3d52b6007cc23 with error 'Error: DatabaseEntry with ID '125' does not exist'
On other attempts, the interview appears to succeed but then fails at the configure step with:
[date] z2m: Failed to configure 'Homelab ventilador', attempt 1 (TypeError: Bind 0x70b3d52b6007cc23/1 genOnOff from '0x8c65a3fffe54d2e5/1' failed (Cannot read properties of undefined (reading 'save'))
at Endpoint.save (/opt/zigbee2mqtt/node_modules/.pnpm/zigbee-herdsman@10.6.1/node_modules/zigbee-herdsman/src/controller/model/endpoint.ts:748:25)
at Endpoint.addBindingInternal (/opt/zigbee2mqtt/node_modules/.pnpm/zigbee-herdsman@10.6.1/node_modules/zigbee-herdsman/src/controller/model/endpoint.ts:701:18)
at Endpoint.bind (/opt/zigbee2mqtt/node_modules/.pnpm/zigbee-herdsman@10.6.1/node_modules/zigbee-herdsman/src/controller/model/endpoint.ts:737:18)
at setupAttributes (/opt/zigbee2mqtt/node_modules/.pnpm/zigbee-herdsman-converters@26.76.0/node_modules/zigbee-herdsman-converters/src/lib/modernExtend.ts:204:13)
at /opt/zigbee2mqtt/node_modules/.pnpm/zigbee-herdsman-converters@26.76.0/node_modules/zigbee-herdsman-converters/src/lib/modernExtend.ts:620:17
at Object.configure (/opt/zigbee2mqtt/node_modules/.pnpm/zigbee-herdsman-converters@26.76.0/node_modules/zigbee-herdsman-converters/src/index.ts:363:21)
at Configure.configure (/opt/zigbee2mqtt/lib/extension/configure.ts:135:13)
at EventEmitter.wrappedCallback (/opt/zigbee2mqtt/lib/eventBus.ts:252:17))
[date] zh:controller:endpoint: Tried to get unknown/deleted device 0x70b3d52b6007cc23 from endpoint 1.
[date] zh:controller: Interview failed for '0x70b3d52b6007cc23 with error 'Error: DatabaseEntry with ID '125' does not exist'
Note the bind attempt targets 0x8c65a3fffe54d2e5 — the coordinator's IEEE address, preserved from before the hardware migration.
What I've ruled out
Notes
My hypothesis (unconfirmed)
I suspect the coordinator migration (restoring an coordinator_backup.json from a prior physical adapter onto a new one, preserving the coordinator IEEE address) leaves some devices' pre-migration binds[] entries (pointing to the coordinator's endpoint) in a state that causes Endpoint.bind() / addBindingInternal() to fail when the destination endpoint object (the coordinator's own endpoint, resolved by looking up its ieeeAddr in the current in-memory device list) can't be resolved correctly — possibly because the newly-rejoining device is assigned a fresh internal database ID that races with or conflicts with something in how the coordinator's own endpoint object is referenced during Endpoint.save().
This would explain why:
Devices that were already joined before the migration and never left the network are unaffected (thousands of successful reports/commands from 100+ other devices with no issues)
Only devices doing a fresh interview+configure cycle after the migration hit this
The failure is 100% reproducible for affected devices, regardless of environment (disk space, container state, Z2M version)
Contributor guide
First steps
- Read the whole issue, then the project's contributing guide.
- Comment on the issue to say you are picking it up — it saves two people doing the same work.
- Fork the repository and make your change on a branch.
- Open a pull request that references the issue number.
Research direction
Start with the failing path in zigbee-herdsman/src/controller/model/endpoint.ts, especially Endpoint.save and addBindingInternal, then follow the calls through zigbee-herdsman-converters/src/lib/modernExtend.ts and lib/extension/configure.ts. Reproduce the coordinator_backup.json migration and rejoin flow using the affected devices and debug logs. Done means affected devices complete interview and configuration without the DatabaseEntry or undefined save errors and are persisted in database.db.
Written by the indexing model from the issue text.
Assessment
- Tech stack
- typescript
- Domain
- backend, database, embedded-iot
- Issue type
- Bug
- Difficulty
- 4/5
- Estimated time
- 3-5 days
- Activity status
- Quiet
- Clarity
- Mostly clear
- Newbie friendliness
- 45/100