Technical Deep DiveNetworkingTroubleshooting
May 21, 2026
8 min read

Beyond the Exception Code: Diagnosing TCP Session Exhaustion in Modbus Communications

When the SCADA times out and the PLC returns absolute silence — no exception code, no TCP RST — the fault is not in the Modbus application layer. It is in the transport layer beneath it.

The Modbus specification outlines predictable failure modes: Illegal Data Address (02), Slave Device Busy (06). When these codes appear, the troubleshooting path is clear — check addressing or manage master polling rates.

The most persistent and infuriating failures, however, manifest as a complete communication blackout. The SCADA times out, the client retries, and the slave PLC offers zero response. No Modbus Exception Code, no TCP RST, just protocol silence. This phenomenon — often misdiagnosed as a simple network fault — is fundamentally a Layer 4 (TCP) session exhaustion problem masquerading as a Layer 7 (Modbus) failure.

This article targets the experienced engineer who has already checked the physical cable and confirmed the unit ID. We skip the basics and focus on the mechanics of why the PLC refuses to even acknowledge the request.

The TCP Handshake: The Prerequisite for Failure Reporting

Modbus TCP operations rely entirely on an established TCP connection. If the initial connection setup fails, the application layer never loads the request — hence no Exception Code can be generated. The system is failing before it can even complain.

The Core Problem

Network traffic is dropped at the PLC's embedded TCP/IP stack or intermediate security hardware, leaving the client waiting for a phantom acknowledgment. The Modbus layer is never reached.

Three Primary Mechanisms of TCP Silence

When you send a Modbus request and receive only a timeout, the culprit lies in the management of the underlying transport layer. There are three distinct failure modes, each with its own diagnostic signature.

1. Full Connection Backlog Queue (Resource Denial)

Every PLC or embedded device has a hard limit on simultaneous active TCP sockets it can maintain. This limit is governed by the firmware's configuration of the TCP/IP stack, not Modbus standards.

The Mechanism: If a PLC is configured to handle N connections (e.g., N = 16), and a legitimate master attempts to initiate connection N + 1 by sending a SYN packet, the stack often silently discards the SYN packet.

The Diagnostic Indicator: The client waits for the configured TCP Retransmission Timeout (often 3 seconds) before retrying. Wireshark will show repeated client SYN packets hitting the PLC's IP with no SYN-ACK response.

The Fix: If the hardware permits, increase the maximum concurrent session limit. If not, implement intelligent master scheduling — such as a dedicated communication server — to cap the number of concurrently polling clients.

2. Zombie Sessions (The Idle Connection Hold)

This occurs when a TCP connection is opened by a temporary client — a laptop used for configuration, for instance — but is not gracefully closed via a FIN packet before the physical link is severed or the application crashes.

The Mechanism: Modbus TCP lacks native keep-alive mechanisms. In the absence of application-level polling, the PLC maintains the half-open socket in memory, waiting for activity that will never arrive. If the active connection count is reached by these "zombies," new legitimate requests are denied.

The Diagnostic Indicator: System logs on the PLC (if accessible) will show a high number of "Active Sockets" even when no HMI or historian is running. The protocol stack is simply holding the line open.

The Fix: Implement OS-level TCP Keep-Alives on the client side and, critically, on the PLC side if the firmware supports it. A short timer (30–60 seconds) forces the stack to probe idle sockets, triggering a RST or FIN exchange and freeing the slot.

3. Security Gateways and DoS Filtering

Industrial firewalls, DMZs, or context-aware network segmentation devices (Layer 3/4) often impose packet rate limitations to mitigate Denial-of-Service attacks.

The Mechanism: A Modbus Master configured with aggressive polling can generate traffic rates that exceed the firewall's threshold for an established IP. The firewall silently drops the packet to protect the internal network segment rather than forwarding it.

The Diagnostic Indicator: Analyzing traffic before and after the firewall reveals the packet drop. The firewall's state logs will show the source IP being temporarily rate-limited or blackholed.

The Fix: Configure the firewall to whitelist the specific Modbus function codes (FC 01–06) from the Master IP, or explicitly raise the acceptable packet-per-second rate threshold for that specific port (typically 502).

The Danger of Ambiguous Timeouts

When a Modbus Exception Code is returned, the integrator knows the issue is within the PLC's control logic or addressing scheme. When a Socket Timeout occurs, the error is ambiguous: is the network down, or is the PLC resource-starved?

A robust system requires differentiating these failure states explicitly:

1

Protocol Exception (e.g., Code 02): Issue requires logic review — check the SCADA tag configuration and register addressing.

2

Socket Timeout (Silence): Issue requires network stack and resource review — investigate PLC firmware socket limits, firewall rules, and session counts.

The Critical Distinction

Engineers must move past assuming a timeout implies a line-of-sight failure. The silence often indicates that the PLC is aware of the request but is intentionally refusing to service it due to internal capacity constraints — communicated at the transport layer, not the application layer.

Diagnostic Checklist: No Response from PLC

1

Capture with Wireshark. Confirm SYN packets reach the PLC IP. If repeated SYNs go unanswered, the backlog queue is full — investigate session count at the firmware level.

2

Check PLC socket diagnostics for inflated "Active Connections" counts with no corresponding active clients. Restart the PLC or force a firmware-level socket flush to confirm zombie sessions are the culprit.

3

If the PLC responds when bypassing the firewall but not through it, inspect the firewall's rate-limit and whitelist configuration for port 502. Compare packet counts on both sides of the device.

4

Enable TCP Keep-Alives on all persistent Modbus clients. Set the idle probe interval to 30–60 seconds. This alone eliminates zombie accumulation from poorly terminated connections.

Modbus Connect shows you the TCP connection lifecycle alongside every Modbus transaction — so you can see whether silence is coming from the wire, the stack, or the firewall before you escalate. See what Modbus Connect can do →

Catch Session Exhaustion Before It Becomes an Outage

A Modbus client that reports connection attempts alongside transaction results lets you distinguish a full backlog queue from a downed link in seconds — without guessing. Modbus Connect logs every connection event so the transport layer failure is visible, not just the application-layer symptom.

Get Started with Modbus Connect

  • Monitor connection establishment alongside register reads to see where the failure occurs in the handshake
  • Configure TCP Keep-Alive intervals per session to prevent zombie socket accumulation over long deployments
  • Differentiate Modbus exception codes from socket timeouts in the activity log to route issues to the right team
  • Test polling rate thresholds before firewalls by controlling request cadence from within the client
Download Free Beta →