Repository navigation
SIGSEGV (exit 139) when _discover_route() called for unknown NWK — v1.1.0 regression #277
Description
Summary
zigpy-znp v1.1.0 introduced a SIGSEGV regression via PR #273 ("Retry after route rediscovery on NWK_NO_ROUTE in send_packet"). When a relay message arrives from an NWK address not in zigpy's device registry, zigpy calls _discover_unknown_device(), which issues a ZDO IEEE_addr_req to that NWK. send_packet then checks for an active route, finds none, and calls _discover_route(nwk). The ZDO.ExtRouteDisc.Req call to the ZNP stack crashes the HA process (SIGSEGV, Python exit code 139) when the destination NWK has no routing table entry at all.
This did not occur with v1.0.0 because NWK_NO_ROUTE was returned as an error and propagated without triggering route rediscovery.
Environment
| Component | Version |
|---|---|
| HA Core | 2026.6.4 |
| ZHA | 2.0.0 |
| zigpy | 1.6.0 |
| zigpy-znp | 1.1.0 |
| Coordinator | SMLIGHT SLZB-MR1 (CC2652P7, ZNP, port 7638) |
| Python | 3.14 |
Reproduction
- Have one or more Zigbee devices on the mesh that are not in zigpy's device registry (e.g. devices removed from ZHA without being factory-reset, or devices from a previous coordinator that retained network credentials).
- Wait for the device to broadcast a routing relay message (~30 min interval for routers).
handle_relays()receives the relay, failsget_device(nwk=X), and calls_discover_unknown_device(X)._discover_unknown_device()callszigpy.zdo.broadcast(IEEE_addr_req, NWKAddrOfInterest=X).send_packet()(zigpy-znp) detects the ZDO destination has no route and calls_discover_route(X)._znp.request(ZDO.ExtRouteDisc.Req(Dst=X, Options=UNICAST, Radius=30))causes SIGSEGV.
Supervisor log shows Watchdog found Home Assistant exited with code 139 every ~30 minutes, correlating exactly with the ghost device's relay heartbeat interval.
Crash signature (HA Core log, faulthandler output)
File ".../zigpy/application.py", line 1703, in _device
File ".../zigpy/application.py", line 1658, in get_device
File ".../zigpy/application.py", line 1090, in request
Supervisor: WARNING [supervisor.homeassistant.core] Watchdog found Home Assistant exited with code 139, restarting...
Affected code path
# zigpy_znp/zigbee/application.py — send_packet()
if (
packet.dst_ep == ZDO_ENDPOINT
and dst_addr.mode == t.AddrMode.NWK
and dst_addr.address != self.state.node_info.nwk
):
route_status = await self._znp.request(
c.ZDO.ExtRouteChk.Req(Dst=dst_addr.address, ...)
)
if route_status.Status != c.zdo.RoutingStatus.SUCCESS:
await self._discover_route(dst_addr.address) # ← crashes when no routing table entry exists# zigpy_znp/zigbee/application.py — _discover_route()
await self._znp.request(
c.ZDO.ExtRouteDisc.Req(
Dst=nwk, # unknown NWK — no routing table entry
Options=c.zdo.RouteDiscoveryOptions.UNICAST,
Radius=30,
),
)Suggested fix
Guard _discover_route() (or the ExtRouteDisc.Req call) against the case where device is None (i.e. the destination NWK is not in the zigpy device registry). A device unknown to zigpy cannot have a route rediscovered in a meaningful way, and the ZNP stack crashes on the attempt.
Alternatively, _discover_unknown_device() in zigpy could be the layer that guards this — but the SIGSEGV is in the ZNP stack, so the guard should be in zigpy-znp.
Workaround
Patch handle_relays in zigpy/application.py to skip _discover_unknown_device():
except KeyError:
LOGGER.warning("Received relays from an unknown device: %s", nwk)
return # skip discovery — crashes ZNP via _discover_route on unknown NWKThis restores v1.0.0 behaviour (warn and return) and eliminates the crash.
References
- PR Retry after route rediscovery on
NWK_NO_ROUTEinsend_packet#273 (introduced regression): Retry after route rediscovery onNWK_NO_ROUTEinsend_packet#273 - PR Fix
ZNPCoordinator.request()rejecting new zigpy kwargs #272 (companion fix): FixZNPCoordinator.request()rejecting new zigpy kwargs #272 - zigpy PR #1824 (upstream change that triggered these ZNP fixes): Move application-level retries into zigpy zigpy#1824
- Closed stale PR that attempted a similar fix in zigpy: Support devices with temporarily unknown IEEE or NWK addresses zigpy#933
Metadata
Metadata
Assignees
Labels
Type
Fields
Priority
Activity