Dbus-modbus-client crashes every 32 s as soon as the device list contains unreachable addresses

An outdated Devices list causes the Modbus driver to crash in a loop, making all energy meters disappear from D-Bus twice a minute. On this system, this escalated to a GX restarting 20–40 times a day for 16 days.

dbus-modbus-client crashes with SIGSEGV during probe_devices() when /Settings/ModbusClient/tcp/Devices contains addresses that are unreachable on the current network. The service is restarted by the supervisor and crashes again during the next scan cycle. This results in a stable crash loop with a period of approximately 31.7 seconds.

With each crash, all Modbus energy meters are removed from D-Bus. On an ESS system, this means that the source of the grid measurement constantly switches between the actual grid meter and the inverter’s internal measurement, resulting in continuous back-and-forth charging and discharging.

The outdated entries arise during normal use: they accumulate when a site changes router or subnet. AutoScan adds devices, but nothing ever removes them.

Affected system

GX device MultiPlus-II GX · /proc/device-tree/model = “MultiPlus-II” · platform nanopi
Venus OS v3.79 build 20260826152305 (Large). Also observed on v3.75, v3.73 and v3.71.
Driver /opt/victronenergy/dbus-modbus-client/dbus-modbus-client.py VERSION = ‘1.80’
Meters 3 × Energy Meter VM-3P75CT, firmware 70143, Modbus UDP port 502
Inverter 3 × MultiPlus-II 48/5000/70-50, 3-phase, ESS (Hub4Mode 1)
Battery Pylontech via BMS-Can — healthy throughout the entire measurement period, no alarms

The trigger: outdated device list

The value of /Settings/ModbusClient/tcp/Devices contained 18 entries, of which only 3 actually existed. Ten of them pointed to subnets that do not exist at all on this network — remnants of previous routers.

Address Count Status
192.168.178.24 · .66 · .115 3 Actual VM-3P75CT meters
192.168.178.12 · .17 · .27 · .69 · .118 5 Outdated — host absent, subnet is correct
192.168.68.114 · .115 · .120 · .123 · .125 5 Outdated — subnet does not exist
192.168.86.31 · .39 · .42 · .43 · .44 5 Outdated — subnet does not exist

Crash signature

Output from the fatal fault handler. The crash occurs in the probe path, while reading holding registers from an unreachable peer:

  File "pymodbus/client/sync.py", line 89 in recv
  File "pymodbus/framer/__init__.py", line 49 in recvPacket
  File "pymodbus/transaction.py", line 367 in _recv
  File "pymodbus/transaction.py", line 299 in _transact
  File "pymodbus/transaction.py", line 175 in execute
  File "pymodbus/client/sync.py", line 109 in execute
  File "/opt/victronenergy/dbus-modbus-client/client.py", line 32 in execute
  File "pymodbus/client/common.py", line 114 in read_holding_registers
  File "/opt/victronenergy/dbus-modbus-client/client.py", line 38 in read_registers
  File "/opt/victronenergy/dbus-modbus-client/probe.py", line 113 in probe
  File "/opt/victronenergy/dbus-modbus-client/probe.py", line 43 in probe
  File "/opt/victronenergy/dbus-modbus-client/dbus-modbus-client.py", line 168 in probe_devices
  File "/opt/victronenergy/dbus-modbus-client/dbus-modbus-client.py", line 259 in update
  File "/opt/victronenergy/dbus-modbus-client/dbus-modbus-client.py", line 304 in update
  File "/opt/victronenergy/dbus-modbus-client/dbus-modbus-client.py", line 270 in update_timer
  File "gi/overrides/GLib.py", line 497 in run
  File "/opt/victronenergy/dbus-modbus-client/dbus-modbus-client.py", line 452 in main

Recorded by the crash logger as: Process NNNN (dbus-modbus-cli) terminated with signal 11 (SEGV)

Crash frequency — measured live

20:52:05  *** starting dbus-modbus-client ***
20:52:37  *** starting dbus-modbus-client ***   ← +32s
20:53:08  *** starting dbus-modbus-client ***   ← +31s
20:53:40  *** starting dbus-modbus-client ***   ← +32s
20:54:12  *** starting dbus-modbus-client ***   ← +32s
20:54:44  *** starting dbus-modbus-client ***   ← +32s

Steps to reproduce

  1. Configure a GX device with one or more Modbus TCP/UDP energy meters (here: 3 × VM-3P75CT on UDP port 502).
  2. Add unreachable addresses to /Settings/ModbusClient/tcp/Devices — for example, on a subnet to which the GX has no connection. In practice, this happens automatically when the site’s router or IP range is changed after the meters have previously been discovered.
  3. Leave AutoScan enabled and allow the scan cycle to run.
  4. Observed: dbus-modbus-client crashes approximately every 32 s and removes all meters with each crash.
    Expected: unreachable addresses time out and are skipped; the driver continues servicing the reachable devices.

Reducing the list to only reachable devices stops the crash immediately:

dbus -y com.victronenergy.settings /Settings/ModbusClient/tcp/Devices SetValue \
  "udp:192.168.178.24:502:1,udp:192.168.178.66:502:1,udp:192.168.178.115:502:1"
svc -t /service/dbus-modbus-client

Good report @stoffelsmichiel

I have forwarded it onto the developers.

Thanks