In modern industrial facilities, Ethernet-to-serial Modbus gateways (such as Moxa MGate MB3180/MB3280, Schneider EGX100/EGX300, Advantech ADAM-4572, Siemens, and ICP DAS) connect supervisory SCADA networks to downstream serial RTU networks. However, when an Ethernet client sends a request that the gateway cannot route internally, the gateway responds with Modbus Exception Code 10 (hexadecimal 0x0A): "Gateway Path Unavailable".
Unlike standard Modbus exceptions that originate from the end-device PLC or sensor (such as Exception 01 Illegal Function or Exception 02 Illegal Data Address), Exception 10 is generated exclusively by the intermediate gateway hardware itself. This engineering guide explains the exact protocol mechanics behind Exception 10, how it differs from Exception 11, and the step-by-step checklist to resolve it.
What is Modbus Exception Code 10 (0x0A)?
Defined in the official Modbus Application Protocol Specification V1.1b3, Exception Code 0x0A (10 decimal) signifies that "the gateway was unable to allocate an internal communication path from the input port to the output port for processing the request." In practice, this means the gateway has no valid routing rule for the requested Unit ID, or the designated physical serial port is disabled, busy, or unconfigured.
Exception 10 vs Exception 11: Key Distinction
Industrial engineers frequently confuse Exception 10 with Exception 11 because both are generated by Modbus gateways. Understanding the fundamental difference is essential for rapid diagnosis:
| Exception | Hex Code | Official Name | Root Location | What Happened on the Wire? |
|---|---|---|---|---|
| Exception 10 | 0x0A |
Gateway Path Unavailable | Inside the Gateway | The gateway aborted the request internally without transmitting onto the serial bus because no route exists for that Unit ID, or the port is disabled. |
| Exception 11 | 0x0B |
Gateway Target Device Failed to Respond | Downstream Serial Bus | The gateway converted and transmitted the RTU frame on RS-485, but the target slave device never replied before the timeout expired. |
Hex Packet Wire Analysis of Exception Code 10
Examining packet captures in Wireshark or serial analyzers illustrates exactly how the gateway signals path unavailability to the polling master.
1. Client Modbus TCP Request
A SCADA client sends a request to read Holding Register 40001 (address 0x0000) for Unit Identifier 16 through a 2-port gateway at IP 192.168.1.50:
[MBAP Header] [PDU]
00 01 00 00 00 06 10 03 00 00 00 02
00 01 : Transaction Identifier (1)
00 00 : Protocol Identifier (0 = Modbus)
00 06 : Message Length (6 bytes follow)
10 : Unit Identifier (Slave Address = 16)
03 : Function Code 03 (Read Holding Registers)
00 00 : Starting Register Address (40001)
00 02 : Quantity of Registers (2 registers)
2. Gateway Exception Response
Because the gateway administrator only configured routing rules for Unit IDs 1 through 10 on COM1 and Unit IDs 20 through 30 on COM2, the gateway finds no matching path for Unit ID 16. It immediately replies with an error frame without sending any RS-485 bits:
[MBAP Header] [Exception PDU]
00 01 00 00 00 03 10 83 0A
00 01 : Transaction Identifier (Matches Request 1)
00 00 : Protocol Identifier (0 = Modbus)
00 03 : Message Length (3 bytes follow)
10 : Unit Identifier (16)
83 : Error Code (Function Code 03 + 0x80)
0A : Exception Code 10 (Gateway Path Unavailable)
5 Common Root Causes and Engineering Fixes
1. Unmapped or Misconfigured Unit Identifier (Slave ID)
Cause: In multi-port gateways (such as Moxa MGate MB3280 with 2 serial ports or MB3480 with 4 ports), the gateway maintains an internal routing table mapping ranges of Unit IDs to physical COM ports. If your SCADA requests Unit ID 12, but the gateway configuration table does not map Unit ID 12 to any COM port, the gateway immediately returns Exception 10.
Fix: Log in to the gateway's web console. Navigate to Protocol Settings → Modbus Routing. Ensure the routing table includes the specific Unit ID requested by the client, or set a default fallback route to the intended serial port.
2. Serial COM Port Disabled or Set to Wrong Protocol
Cause: The requested Unit ID is mapped to a serial port, but that serial port is administratively disabled, configured for an incompatible operating mode (e.g. transparent TCP Server mode instead of Modbus RTU Master mode), or set to an invalid hardware standard (e.g. RS-232 instead of RS-485 2-wire).
Fix: Verify that the serial port operating mode is set to Modbus RTU / Modbus Slave mode. If your physical field wiring uses a 2-wire differential pair (Data+ and Data-), ensure the port mode is explicitly toggled to RS-485 2-Wire.
3. Multi-Master Contention and Internal Buffer Exhaustion
Cause: When multiple Modbus TCP masters (e.g., primary SCADA, redundant SCADA, local HMI, and historian) poll a single-port gateway simultaneously at aggressive cycle rates (e.g. 50ms intervals), the gateway's serial conversion queue becomes saturated. While the RS-485 bus is busy servicing one master's transaction, the gateway may reject new incoming TCP connections with Exception 10 due to buffer exhaustion.
Fix: Increase the polling interval in your SCADA software from 50ms to 250ms–500ms. In the gateway configuration, enable Multi-Master FIFO Queuing and increase the maximum queue depth from 32 to 128 packets.
4. IP/Port Virtual Mapping Conflicts
Cause: Some industrial gateways map serial ports by distinct TCP listening ports (e.g., TCP 502 for COM1, TCP 503 for COM2, TCP 504 for COM3) rather than by Unit ID. If your SCADA connects to TCP port 502 and asks for a device connected to COM2, the gateway returns Exception 10.
Fix: Review the gateway documentation to verify whether routing is based on Unit ID Routing or TCP Port Mapping. If TCP port mapping is used, adjust your SCADA client connection parameters accordingly.
5. Gateway Firmware Bug or Unhandled Slave Crash
Cause: Legacy gateways running older firmware can experience state machine lockups on their serial UART drivers if an electrical noise burst occurs on the RS-485 line, causing the internal port handler to enter an unresponsive fault state.
Fix: Power-cycle the gateway. If communication restores temporarily, upgrade the gateway firmware to the latest manufacturer release to resolve known UART driver hang conditions.
Python Script to Diagnose Gateway Path Availability
Use this diagnostic script with pymodbus to test whether a gateway correctly routes specific Unit IDs or returns Exception 10:
from pymodbus.client import ModbusTcpClient
import sys
def test_gateway_route(ip, port, unit_id, register_addr=0):
client = ModbusTcpClient(ip, port=port, timeout=3.0)
if not client.connect():
print(f"Failed to connect to gateway at {ip}:{port}")
return
print(f"Polling Gateway {ip}:{port} for Unit ID {unit_id}...")
response = client.read_holding_registers(address=register_addr, count=1, slave=unit_id)
if response.isError():
if hasattr(response, 'exception_code'):
code = response.exception_code
if code == 0x0A: # 10 decimal
print(f"[ERROR 10] Gateway Path Unavailable for Unit ID {unit_id}!")
print(" -> Check gateway internal routing table and serial port state.")
elif code == 0x0B: # 11 decimal
print(f"[ERROR 11] Gateway Target Device Failed to Respond for Unit ID {unit_id}.")
print(" -> Path exists, but slave did not reply before timeout.")
else:
print(f"[MODBUS EXCEPTION] Code {code} (0x{code:02X})")
else:
print(f"Communication Error: {response}")
else:
print(f"[SUCCESS] Route Valid! Received value: {response.registers[0]}")
client.close()
if __name__ == '__main__':
# Test Unit IDs 1 through 5 on gateway
gateway_ip = "192.168.1.50"
for uid in range(1, 6):
test_gateway_route(gateway_ip, 502, uid)
Frequently Asked Questions
What does Modbus Exception Code 10 (0x0A) mean?
Modbus Exception Code 10 (0x0A - 'Gateway Path Unavailable') is generated by a Modbus TCP-to-RTU gateway when it cannot route a request internally because the target Unit ID is unassigned, the destination serial port is disabled, or communication buffers are locked.
What is the difference between Exception 10 and Exception 11?
Exception 10 indicates that the gateway itself failed to route the request onto any physical serial port. Exception 11 means the gateway routed the request to the RS-485 line, but the downstream device did not reply in time.
Why does Moxa MGate return Exception Code 10?
Moxa MGate gateways return Exception 10 when the requested Slave ID is not defined in the 'Modbus Routing' table, when COM ports are assigned to conflicting operating modes, or during multi-master buffer saturation.
How do I fix Gateway Path Unavailable?
Open the gateway's web configuration interface, navigate to the Modbus routing table, ensure the requested Unit ID is assigned to an active COM port, confirm the serial interface is set to RS-485 2-wire, and verify that baud rate settings match the physical bus.
Can I test gateway routing using ModbusSimulator?
Yes. You can use ModbusSimulator to emulate virtual slave devices on specific COM ports or simulate Modbus TCP masters, allowing you to test routing tables and multi-master concurrency before commissioning field devices.