Problem Overview
Modbus TCP devices frequently exhibit a specific failure pattern: the device drops its TCP connection (link loss, device reboot, switch reboot, IP change, or a transient timeout), but the SCADA master never re-establishes the session. Holdings, Input Registers, Coils, and Discrete Inputs freeze at their last known value, and the channel remains in a Connected-but-Unresponsive state until a warm reset, service restart, or manual socket close is performed.
This article targets the failure pattern observed in EcoStruxure Geo SCADA Expert (formerly ClearSCADA) and analogous Schneider Electric SCADA drivers, where the slave device (commonly a Sepam protection relay accessed through a P2CDS622 communication module, an EM3500 series meter, an Acti9 Smartlink, or a third-party power meter) disconnects and the master fails to reopen the TCP socket. The same troubleshooting matrix applies to any Modbus/TCP master that exposes a per-channel AutoReconnect, ConnectTimeout, RequestTimeout, and IdleDisconnect configuration block.
Log tab shows the last successful request timestamp freeze, with no further TX/RX entries and no Disconnected/Reconnecting transition.Root Cause Taxonomy
Reconnection failures cluster into six categories. Identifying the correct one is essential because the corrective action differs.
| Category | Mechanism | Master State | Diagnostic Signal |
|---|---|---|---|
| 1. AutoReconnect disabled | Driver suppresses socket re-open after first failure | Channel Up, no TX/RX | Channel settings show AutoReconnect = FALSE
|
| 2. Half-open socket | Peer reset not detected (no TCP keepalive) | Channel Up, no TX/RX | OS shows ESTABLISHED with no remote endpoint |
| 3. Three-timeout disconnect | Driver drops the channel on consecutive failed polls but never reopens | Channel flaps Up/Down | Log shows Timeout x3 then silence |
| 4. ARP/NAT aging | L2 path cleared, master never issues ARP refresh | Channel Up, no TX/RX | Switch shows MAC entry aged out |
| 5. App-layer desync | MBAP transaction ID drift after reconnect | Channel Up, CRC errors | Log shows Invalid MBAP or Transaction Mismatch
|
| 6. Pool exhaustion | Master closes socket but does not return it to the pool | Channel Down after N cycles | Log shows No available connections
|
AutoReconnect Configuration
The first control to verify is the per-channel AutoReconnect flag. In Geo SCADA, this property lives on the Modbus Advanced Generic Direct outstation or the Modbus TCP/IP driver channel configuration page. When AutoReconnect is FALSE, the driver intentionally suppresses reconnection attempts after the channel enters a failure state to avoid flooding the network during a known outage.
- Open the Geo SCADA ViewX application and connect to the server.
- Navigate to the System Configuration node and expand the SCADA host.
- Right-click the affected Channel and select Properties.
- Select the Modbus tab (or the driver-specific tab: Modbus Advanced Generic Direct, Modbus RTU over TCP, etc.).
- Set AutoReconnect = TRUE.
- Click Apply, then OK.
AutoReconnect property exists. Do not conflate it with the line-driver Reconnect on Error checkbox, which controls the COM port handle only.TCP Keepalive Parameters
Even with AutoReconnect enabled, the driver cannot detect a half-open socket faster than the OS-level TCP keepalive cadence. The relevant knobs live in the operating system registry on Windows hosts running the Geo SCADA server.
| Windows Registry Key | Recommended Value | Meaning |
|---|---|---|
HKLM\System\CurrentControlSet\Services\Tcpip\Parameters\KeepAliveTime |
30000 (30 s) | Idle time (ms) before first keepalive probe |
HKLM\System\CurrentControlSet\Services\Tcpip\Parameters\KeepAliveInterval |
1000 (1 s) | Interval (ms) between successive probes |
HKLM\System\CurrentControlSet\Services\Tcpip\Parameters\TcpMaxDataRetransmissions |
5 | Probes sent before declaring the connection dead |
HKLM\System\CurrentControlSet\Services\Tcpip\Parameters\TcpMaxConnectRetransmissions |
3 | SYN retransmits on initial connect |
With the values above, the master detects a dead peer in approximately 30 + (5 × 1) = 35 s. This figure must be shorter than the device's TCP idle disconnect timer to avoid a half-open condition. Sepam P2CDS622 modules default to a 60-second TCP idle timeout; if the master polling interval is 30 s and the request timeout is 5 s, the keepalive cadence above is safe.
netsh int tcp show global displays the auto-tuning level, and Get-NetTCPConnection -State Established | Select-Object LocalAddress,RemoteAddress,OwningProcess enumerates live sockets. On Linux SCADA hosts, the equivalent sysctl knobs are net.ipv4.tcp_keepalive_time, net.ipv4.tcp_keepalive_intvl, and net.ipv4.tcp_keepalive_probes.Timeout and Retry Matrix
Three-timeout disconnects are the most common reconnection failure in Industrial Automation Engineer practice. A driver typically drops the channel only after three consecutive failed polls; the log then goes silent because the driver has not yet observed the peer returning to service.
| Parameter | Geo SCADA Property | Conservative | Aggressive | Effect |
|---|---|---|---|---|
| Connect timeout | ConnectTimeout |
10000 ms | 3000 ms | Time to wait for TCP SYN-ACK |
| Request timeout | RequestTimeout |
5000 ms | 1500 ms | Time to wait for Modbus response |
| Inter-poll delay | InterPollDelay |
50 ms | 0 ms | Gap between successive register reads |
| Failed-poll threshold | ConsecutiveTimeouts |
3 | 1 | Polls before channel is marked Down |
| Reconnect backoff | ReconnectInterval |
30 s | 5 s | Delay between reconnection attempts |
ConsecutiveTimeouts × RequestTimeout must be less than the application's allowed data-staleness window. If the SCADA is supervising a 100 ms protection interlock, a 15 s stale-data window is unacceptable — set ConsecutiveTimeouts = 1 and ReconnectInterval = 1 s.Polling Strategy and Register Grouping
A reconnection failure can be self-inflicted: a long, contiguous read of 100+ registers that exceeds the device's response window can produce three timeouts, dropping the channel. Partition the polled register set into blocks that complete in well under the RequestTimeout window.
// Recommended block sizing (typical P2CDS622-class devices)
const int MAX_HOLDINGS_PER_REQUEST = 32; // 32 registers ≈ 64 bytes payload
const int MAX_INPUTS_PER_REQUEST = 32;
const int MAX_COILS_PER_REQUEST = 64;
const int POLL_INTERVAL_MS = 2000; // match the device poll cycle
For an IsolationMeter or similar three-phase power meter accessed over Modbus/TCP, the recommended poll plan is:
- Read voltage block (3 × 16-bit registers, function code 0x03) — every 2 s.
- Read current block (3 × 16-bit, FC 0x03) — every 2 s.
- Read energy block (2 × 32-bit, FC 0x03) — every 10 s.
- Read status word (1 × 16-bit, FC 0x03) — every 5 s.
Diagnostic Logging Procedure
The Geo SCADA Log tab on the channel and outstation objects is the primary diagnostic. Configure verbose logging before reproducing the fault.
- Right-click the affected Channel and choose Properties → Logging.
- Set Log Level = Debug and Log Diagnostics = TRUE.
- Apply and let the system run for one full polling cycle.
- Export the log via the Logs node (right-click → Export) and search for the strings
TX:,RX:,TIMEOUT,DISCONNECT,RECONNECT, andMBAP.
A healthy channel log shows repeating TX: 00 01 00 00 00 06 01 03 00 00 00 0A followed by RX: within the request-timeout window. After a fault, look for these failure signatures:
| Log Pattern | Interpretation | Action |
|---|---|---|
TX: then silence for > 5× RequestTimeout |
Peer is unreachable; driver not retrying | Enable AutoReconnect; reduce ReconnectInterval |
TIMEOUT × 3 then DISCONNECT then silence |
Three-timeout rule triggered | Reduce ConsecutiveTimeouts to 1; check LAN path |
DISCONNECT then RECONNECT then DISCONNECT loop |
Peer resets the socket on every open | Check device's MaxConnections / MaxSessions |
RX: 00 02 00 00 00 03 01 83 02 |
Illegal Function (exception 0x02) | Address not supported on this device; do not retry |
RX: 00 02 00 00 00 03 01 83 04 |
Slave Device Failure (exception 0x04) | Device is recovering; pause polling for 10 s |
Verification with a Modbus Simulator
Before declaring a channel fixed, reproduce the failure with a controllable simulator. The Modbus RSIM (Modbus Server Simulator from Software Toolbox) or diagslave running on a laptop is ideal.
- Install the simulator and bind it to TCP port 502 (or 501 for a non-privileged test).
- Configure the Geo SCADA channel to point at
127.0.0.1:502. - Confirm a successful data exchange in the Log tab.
- Simulate a disconnect by changing the simulator's port to 501 while polling is active.
- Wait 60 s and observe the channel state.
- Revert the simulator to port 502.
- Verify that the master reopens the socket automatically, the
RECONNECTline appears in the log, and newRX:entries resume within oneReconnectInterval.
If step 7 fails, the AutoReconnect flag is the next item to check. If the log shows RECONNECT but no RX:, the issue is on the master-side socket pool, not on the network.
Workaround: Forced Channel Reset
When AutoReconnect alone is insufficient — a known limitation of some driver revisions — the field-proven workaround is a scripted channel reset. In Geo SCADA, a Logic program can issue a ChannelReset method call whenever the data-staleness timer exceeds a threshold.
// Pseudocode for a Logic program attached to the channel
IF LastUpdateTime < (CurrentTime - 60) THEN
CALL ChannelReset(ChannelName);
LOG("Forced channel reset at " + CurrentTime);
END_IF;
Edge Cases and Field Cautions
Five situations produce reconnection failures that masquerade as a driver bug:
-
Device's Max Sessions = 1. A legacy Sepam or PM5000 meter accepts one TCP connection at a time. If a second tool (Modscan, Modbus Poll) is open, the SCADA's reconnection attempt is rejected with
ECONNREFUSEDuntil the rogue client is closed. Usenetstat -an | findstr :502on Windows to enumerate active sessions. - Firewall idle timeout. Corporate Windows Firewall and most industrial firewalls default to a 60-minute idle disconnect. A device polled every 65 minutes will be killed by the firewall, not the driver. Set the firewall's TCP idle timeout to a value higher than the polling interval.
- VLAN or subnet change after device reboot. If the device re-acquires a different IP via DHCP, the master still polls the old IP. Bind the channel to a hostname resolved by DNS, or use a static IP lease on the DHCP server.
- Modbus Security / Modbus TLS proxy. A Modbus Security gateway in front of the device maintains its own session state. The master must support the gateway's keepalive protocol; otherwise the gateway silently drops the inner connection after its own idle timer fires.
- NAT translation in cellular / 4G routers. Each reconnection can land on a different public IP. The Modbus device treats every new connection as a fresh session and discards the old transaction state. Keep the master and device on a private network behind a fixed-IP cellular gateway.
Master-Side Socket Pool Tuning
When AutoReconnect is enabled but the channel flaps every few minutes, the issue is often a socket pool that is not replenished. The relevant Geo SCADA properties on the Modbus TCP driver are:
| Property | Default | Recommended for Power Metering |
|---|---|---|
MaxConnections |
4 | 2 (one primary, one spare) |
IdleTimeout |
60 s | 300 s (or 0 = never) |
KeepAlive |
FALSE | TRUE |
ReuseAddress |
TRUE | TRUE |
IdleTimeout = 0 instructs the driver to hold the socket open between polls. This is correct for a low-latency power meter but should be set to a finite value (e.g. 300 s) if the SCADA is communicating across a cellular link, where the carrier's NAT will reap the socket after a few minutes of silence.
Application-Layer Desync Recovery
Modbus/TCP uses a 16-bit MBAP transaction identifier. If the master increments the ID per request and the device resets its counter on every connect, the first poll after a reconnect can fail with a Transaction ID Mismatch. Modern drivers (including Geo SCADA 2023 R1 and later) handle this transparently by re-issuing the request once after a mismatch. On older revisions, the workaround is to force a transaction-ID reset on every reconnect by toggling ResetMBAPOnConnect = TRUE.
Quick Reference Checklist
- ☐ AutoReconnect = TRUE on the channel
- ☐ ConnectTimeout ≤ 3 s
- ☐ RequestTimeout ≤ 5 s
- ☐ ConsecutiveTimeouts = 1 (for critical data) or 3 (for non-critical)
- ☐ ReconnectInterval ≤ 10 s
- ☐ OS-level keepalive enabled, KeepAliveTime ≤ 30 s
- ☐ Firewall idle timeout > polling interval
- ☐ MaxConnections ≥ 2 on the device
- ☐ Log Level = Debug captured during fault
- ☐ Simulator-based verification completed
FAQ
Why does my Modbus TCP device connect once and then never respond again?
The driver is in a half-open socket state. The peer closed its side (reboot, power cycle, switch reboot) but the master OS still considers the socket ESTABLISHED. Enable OS-level TCP keepalive (KeepAliveTime = 30 s, KeepAliveInterval = 1 s, TcpMaxDataRetransmissions = 5) and set the driver's AutoReconnect = TRUE.
What does the "three timeouts in a row" behavior mean in Modbus drivers?
Many drivers (Ignition, Geo SCADA, KEPServerEX) declare the channel Down only after three consecutive failed polls, to ride out a single packet loss. If the device remains unreachable, the driver must then re-establish the socket; if AutoReconnect is disabled, the channel will not recover. Set ConsecutiveTimeouts = 1 for critical data or enable the driver's auto-reconnect.
How do I verify a Modbus TCP channel is actually reconnecting?
Enable Log Level = Debug on the channel, then disconnect the slave (change its IP, power-cycle it, or change the simulator's port). After the ReconnectInterval has elapsed, look for a RECONNECT line followed by a fresh TX:/RX: pair. If only the RECONNECT appears with no RX:, the driver is failing to re-establish the socket at the OS level — check firewall and TCP keepalive.
What TCP keepalive values should I use for a Schneider P2CDS622 module?
Use KeepAliveTime = 30000 ms, KeepAliveInterval = 1000 ms, and TcpMaxDataRetransmissions = 5. This gives a 35-second dead-peer detection time, which is comfortably below the P2CDS622's 60-second TCP idle timeout. Confirm the values on Windows via netsh int tcp show global or by editing the registry keys under HKLM\System\CurrentControlSet\Services\Tcpip\Parameters.
Can a warm reset of the PLC fix a stuck Modbus channel?
Yes — a controller or service restart tears down all sockets and forces the driver to re-establish from a clean state. This is a workaround, not a fix. The root cause is almost always a missing AutoReconnect flag, an OS-level keepalive configuration that is too long, or a half-open socket left over from a peer reset. Address the root cause to avoid the reset cycle.