ZHA / bellows loses connection to EZSP radio over TCP (ConnectionResetError 104)
Summary
ZHA devices become unavailable after Home Assistant has been running for some time. Restarting Home Assistant temporarily restores the devices. Debug logging shows that ZHA/bellows loses the serial-over-TCP connection to the EZSP radio with:
ConnectionResetError(104, 'Connection reset by peer')
Connection to the radio has been lost
This happens while the ZHA watchdog is reading EZSP counters.
Environment
- Home Assistant: TODO: add exact HA version
- ZHA
- Radio type: EZSP / Silicon Labs
- Transport: TCP socket
- ZHA radio path:
socket://192.168.10.2:8888
- Coordinator hardware: Sonoff ZBBridge / ESP8266
- Coordinator firmware: Tasmota 15.5.0.1
(aec8e23-zbbridge)
- EZSP stack/protocol from log:
bellows@0.49.2
- EZSP protocol version: 8
- Stack version:
6.7.9.0 build 405
- Coordinator IEEE:
2c:11:65:ff:fe:88:25:23
- Zigbee devices:
- Zigbee network:
- Channel: 25
- PAN ID:
0x80FE
Symptoms
- Home Assistant starts and ZHA devices are available.
- After some runtime, all ZHA devices become unavailable / cannot be controlled.
- Restarting Home Assistant restores operation temporarily.
- Restarting only the bridge did not reliably resolve the issue.
- The issue appears to affect the ZHA radio connection, not individual Zigbee devices.
Relevant log excerpt
2026-07-07 18:44:22.001 DEBUG (MainThread) [bellows.zigbee.application] Free buffers status EzspStatus.SUCCESS, value: 243
2026-07-07 18:44:22.001 DEBUG (MainThread) [bellows.zigbee.application] ezsp_counters: [MAC_RX_BROADCAST = 930, MAC_TX_BROADCAST = 336, MAC_RX_UNICAST = 51, MAC_TX_UNICAST_SUCCESS = 45, MAC_TX_UNICAST_RETRY = 77, MAC_TX_UNICAST_FAILED = 16, APS_DATA_RX_BROADCAST = 1, APS_DATA_TX_BROADCAST = 1, APS_DATA_RX_UNICAST = 25, APS_DATA_TX_UNICAST_SUCCESS = 20, APS_DATA_TX_UNICAST_RETRY = 5, APS_DATA_TX_UNICAST_FAILED = 0, ROUTE_DISCOVERY_INITIATED = 4, NEIGHBOR_ADDED = 3, NEIGHBOR_REMOVED = 0, NEIGHBOR_STALE = 2, ... EZSP_FREE_BUFFERS = 243]
2026-07-07 18:44:32.004 DEBUG (MainThread) [zigpy.application] Feeding watchdog
2026-07-07 18:44:32.004 DEBUG (MainThread) [bellows.ezsp.protocol] Sending command readCounters: () {}
2026-07-07 18:44:32.006 DEBUG (bellows.thread_0) [bellows.ash] Sending frame DataFrame(frm_num=3, re_tx=False, ack_num=4, ezsp_frame=b'\x9a\x00\x01\xf1\x00') FLAG
2026-07-07 18:44:32.006 DEBUG (bellows.thread_0) [bellows.ash] Sending data 34d821a9a52a17a67e
2026-07-07 18:44:32.010 DEBUG (bellows.thread_0) [zigpy.serial] Connection lost: ConnectionResetError(104, 'Connection reset by peer')
2026-07-07 18:44:32.011 DEBUG (bellows.thread_0) [bellows.uart] Connection lost: ConnectionResetError(104, 'Connection reset by peer')
2026-07-07 18:44:32.012 DEBUG (MainThread) [zigpy.application] Connection to the radio has been lost: ConnectionResetError(104, 'Connection reset by peer')
2026-07-07 18:44:32.012 DEBUG (MainThread) [homeassistant.components.zha.helpers] Connection to the radio was lost: ConnectionLostEvent(event_type='zha_gateway_message', event='connection_lost', exception=ConnectionResetError(104, 'Connection reset by peer'))
2026-07-07 18:44:32.037 WARNING (bellows.thread_0) [py.warnings] /usr/local/lib/python3.14/asyncio/base_events.py:744: RuntimeWarning: coroutine 'SerialProtocol.disconnect' was never awaited
self._ready.clear()
What looks important
- Before the disconnect, EZSP counters and free buffers look healthy.
- The actual failure is not a Zigbee end-device timeout. It is the TCP/serial connection to the EZSP radio being reset.
- The log ends immediately after the disconnect. There is no visible successful reconnect in this captured log.
- There is also a Python warning:
RuntimeWarning: coroutine 'SerialProtocol.disconnect' was never awaited
which may indicate cleanup/reconnect handling problem after the TCP reset.
Expected behavior
If the TCP connection to an EZSP radio is reset, ZHA/bellows should recover automatically and reconnect without requiring a full Home Assistant restart.
Actual behavior
After the connection reset, ZHA devices remain unavailable until Home Assistant is restarted.
Reproduction
- Configure ZHA with EZSP radio over TCP:
socket://192.168.10.2:8888
- Start Home Assistant.
- Wait until devices become unavailable.
- Observe the log around the time of failure.
ZHA / bellows loses connection to EZSP radio over TCP (ConnectionResetError 104)
Summary
ZHA devices become unavailable after Home Assistant has been running for some time. Restarting Home Assistant temporarily restores the devices. Debug logging shows that ZHA/bellows loses the serial-over-TCP connection to the EZSP radio with:
This happens while the ZHA watchdog is reading EZSP counters.
Environment
socket://192.168.10.2:8888(aec8e23-zbbridge)bellows@0.49.26.7.9.0 build 4052c:11:65:ff:fe:88:25:230x80FESymptoms
Relevant log excerpt
What looks important
RuntimeWarning: coroutine 'SerialProtocol.disconnect' was never awaitedwhich may indicate cleanup/reconnect handling problem after the TCP reset.
Expected behavior
If the TCP connection to an EZSP radio is reset, ZHA/bellows should recover automatically and reconnect without requiring a full Home Assistant restart.
Actual behavior
After the connection reset, ZHA devices remain unavailable until Home Assistant is restarted.
Reproduction
socket://192.168.10.2:8888