What does WaitAfterDisconnect actually tell you?
The Ignition DNP3 driver is the master and the TCP client. It opens a socket to the outstation (RTU), polls, and holds that socket open. When the socket closes, the driver moves to WaitAfterDisconnect, holds off briefly, then reconnects and returns to Connected. Every tag on that device goes to bad quality while the socket is down. When the status flips between Connected and WaitAfterDisconnect about once per second, and tag quality flaps at the same rate, the driver is not stalling. The socket is being torn down right after it is established, and the driver is doing what it is designed to do: reconnect.
Reads still succeeding between drops rules out addressing, port, and basic DNP3 configuration. The master reaches the outstation and gets responses. The question is who ends the TCP session. In the confirmed case, the outstation kept closing the connection, and a packet capture proved it. Other masters on the same RTU staying connected does not clear the RTU. It means the RTU treats this master differently from the others.
Which hop is closing the connection?
Follow the packet. Every TCP session ends with a FIN or an RST, and the source IP of the first one identifies the side that closed it. Check the physical layer first, but a clean reconnect every second looks like a deliberate close at the TCP or application layer, not a flapping link.
| Hop | Role | How it can end the session |
|---|---|---|
| Ignition Gateway (DNP3 driver) | Master / TCP client | Sends FIN after a response timeout or a driver-level error, which the Gateway log shows |
| Gateway host NIC / OS firewall | Local stack | Sends RST if host security software blocks the flow |
| Firewall, NAT, cellular or radio modem | Middlebox | Injects RST on idle timeout, session-table limit, or policy mismatch |
| RTU / outstation | TCP server | Sends FIN or RST when it rejects the master: IP not allowed, address mismatch, or connection slot already taken |
How do the diagnostic options compare?
| Method | Shows who closed the socket | Shows DNP3 frames before the close | Detects middlebox RST | Effort |
|---|---|---|---|---|
| Ignition Gateway logs | Indirectly (driver-side reason only) | No | No | Low |
| Wireshark on the Gateway host | Yes, source IP of FIN/RST | Yes, with the DNP3 dissector | Partly: the RST appears but seems to come from the RTU IP | Low |
| Capture at the RTU end (SPAN/mirror port) | Yes | Yes | Yes, when compared with the Gateway-side capture | Medium |
| RTU event/diagnostic log | Only if the RTU logs its own disconnect reasons | Vendor-dependent | No | Vendor-dependent |
Recommendation: capture with Wireshark on the Gateway host and collect the Gateway logs over the same time window. This combination resolves most cases. Add a second capture at the RTU end only when the Gateway-side trace shows an RST from the RTU IP that the RTU denies sending. That pattern points to a firewall or modem in the path forging the reset.
How do you run the capture and read it?
- On the Gateway server, start Wireshark on the interface that routes to the RTU. Confirm with the route table if the host has several NICs.
- Apply the capture or display filter to isolate the flow.
- Let it run through at least 20-30 status toggles while the Gateway log viewer is open for the same device.
- Apply
tcp.flags.fin == 1 || tcp.flags.reset == 1. For each session, note which IP sends the first FIN or RST. - Remove the flag filter and apply
dnp3. Read the last few frames before each close: did the RTU answer the last request, and do the source and destination DNP3 addresses match the RTU configuration? - Use Statistics > Conversations > TCP to count sessions. One new stream per second, each with a fresh SYN handshake, confirms the reconnect loop.
- Keep the capture and the matching Gateway log excerpt together. The RTU vendor or Ignition support will want both.
| What the trace shows | Meaning | Where to act |
|---|---|---|
| First FIN/RST from RTU IP, RTU confirms it sent it | Outstation rejects this master | RTU configuration |
| First FIN from Gateway IP after an unanswered request | Driver response timeout | Driver timeout settings or RTU response time |
| RST from RTU IP, but not present in the RTU-side capture | Middlebox injected the reset | Firewall/modem session policy |
| RST from Gateway IP with no preceding DNP3 error | Local host security software | Gateway host firewall/AV |
What on the outstation drops one master but keeps the others?
When the RTU sends the close and every other master stays connected, compare this master's identity against what the RTU expects. The recurring causes on DNP3 outstations are:
| Cause | Mechanism | Check |
|---|---|---|
| Duplicate DNP3 master address | Ignition uses the same source address as another client. Many outstations keep one session per master address and close one when the other connects. | Compare the source address in Ignition's device settings with every other master on the RTU |
| Master IP allow-list | The RTU accepts TCP, then closes sessions from IPs not bound to a configured master or channel | RTU master/channel table vs the Gateway IP seen in the capture |
| Connection slot limit | All TCP sessions on the listener are in use, so a new one is accepted and then dropped, or it evicts another | RTU maximum-connection setting vs the number of active masters |
| Redundant or duplicate Gateways | A backup Gateway, or a second device connection to the same RTU, competes for the same master slot | Count distinct Gateway source IPs and ports in Statistics > Conversations |
| Wrong outstation address targeted | Requests go to a DNP3 destination address the RTU does not own on that channel | DNP3 destination address in the frames vs the RTU's configured address |
- Assign Ignition a DNP3 master (source) address that no other client uses, and add it to the RTU's master table with the Gateway's IP.
- If the RTU limits sessions per port, raise the limit or give Ignition its own channel/port on the RTU.
- Disable any second Gateway or duplicate device connection pointing at the same RTU with the same master address.
- Apply the RTU change according to its vendor procedure (some require a restart of the communication channel), then save the Ignition device connection to force a clean reconnect.
How do you verify the connection is stable?
- Watch the device status under the Gateway's OPC UA device connections. It should hold
Connectedwith noWaitAfterDisconnecttransitions. - Trend several DNP3 tags and confirm that quality stays good across many poll cycles.
- Re-run the capture. Statistics > Conversations should show a single long-lived TCP stream from the Gateway to the RTU, with no new SYN handshakes.
- Re-apply
tcp.flags.fin == 1 || tcp.flags.reset == 1over a window at least as long as the RTU's longest configured integrity poll or keepalive interval, and confirm it returns zero packets.
FAQ
How do I tell whether Ignition or the RTU is dropping the DNP3 connection?
Capture on the Gateway host with Wireshark and filter tcp.flags.fin == 1 || tcp.flags.reset == 1. The source IP of the first FIN or RST in each session is the side that closed it. Repeated closes from the RTU IP mean the outstation is ending the session.
Why does only Ignition disconnect when other DNP3 masters on the same RTU stay connected?
The RTU is treating Ignition's session differently. The usual causes are a duplicate DNP3 master address, a Gateway IP missing from the RTU's master allow-list, or an exhausted connection-slot limit. Compare Ignition's source address and IP against the RTU's master table.
How do I confirm the WaitAfterDisconnect loop is fixed?
The device status should hold Connected and tag quality should stay good. A fresh capture should show one persistent TCP stream with no new SYN handshakes. Finally, confirm the FIN/RST filter returns zero packets over at least one full integrity-poll or keepalive interval.