Why exceptions matter
Modbus is a polite protocol. When a slave can't satisfy a request, it doesn't drop the connection or stay silent - it answers, but with the high bit of the function code set, and a single byte of exception information. That byte is the most diagnostic information you'll ever get out of a misbehaving Modbus device. Read it correctly and most "the meter is broken" tickets resolve in under five minutes.
The eleven codes are deceptively similar. Three of them (02, 03, and 04) account for roughly 80% of the exceptions you'll see in the field. The rest are rare but informative. This post covers all of them, in order.
Anatomy of an exception frame
An exception response is three bytes of payload, framed normally:
Unit ID FC | 0x80 ExceptionCode CRC
─────────────────────────────────────────
0x11 0x83 0x02 0x...
▲ ▲ ▲
│ │ └── 02 = Illegal Data Address
│ └── 0x83 = 0x03 (Read Holding) with high bit set
└── slave 17
The function code echoed back is your original function code OR'd with 0x80. So a failing 0x03 Read Holding becomes 0x83, a failing 0x10 Write Multiple becomes 0x90, and so on. The exception byte that follows tells you the specific failure.
Field tip. If your client reports "no response" but a frame capture shows three bytes coming back from the slave, you're getting an exception your client is swallowing silently. This is depressingly common in older clients. Switch to a tool that shows you the wire.
Exception 01 - Illegal Function
The function code you sent is not implemented on this slave. In practice this is almost never "the slave doesn't speak Modbus" - it's "the slave doesn't implement this specific function". The most common offender is 0x17 (Read/Write Multiple) on small embedded slaves that only implement 0x03, 0x06, and 0x10.
How to fix. Check the device's protocol manual for the supported function codes. Fall back to a function code the device implements. If you're polling register pairs as one transaction, split the write into a separate 0x06 or 0x10 request.
Exception 02 - Illegal Data Address
The most common exception in the field, by a wide margin. The slave is telling you that the register address you asked for doesn't exist on this device. This is almost always one of three things:
- You're using the wrong addressing base - the device documents registers as
40001+ (1-based) but the protocol uses 0-based addresses on the wire. - The device's documented register map is wrong (this happens more than vendors admit), and the real start address is elsewhere.
- You're polling beyond the end of a register block. The slave allows you to start at a valid address but the quantity walks off the end.
How to fix. In Coilware Modbus, run the Scan tool's register sweep against a window either side of your target - it classifies each address as OK, illegal, or exception, so you can see exactly where the device's real map starts.
Exception 03 - Illegal Data Value
The address is valid, but the value you tried to write isn't acceptable. Three common cases: you wrote a value out of the legal range for that register; you tried to write to a read-only register; or you wrote a quantity field (in 0x10) that's valid in the spec but not on this slave.
Exception 04 - Slave Device Failure
The slave tried, and failed, to satisfy a valid request. This is the device's way of saying "something is wrong on my end, not yours". Almost always indicates an internal firmware error, a watchdog reset mid-request, or a hardware fault on the device.
Exception 05 - Acknowledge
"I'm working on it." Rare. Some devices (typically flash-write operations) return 05 to tell the master to poll again and wait. If you're not running a long-write transaction and you see this, you probably have a misbehaving gateway translating something it shouldn't.
Exception 06 - Slave Busy
The slave is processing a long-running command and cannot accept a new one. Retry with backoff. If you see this constantly, your poll cadence is faster than the slave's processing budget - slow down, or split the read into smaller chunks.
Exception 08 - Memory Parity Error
Very rare. The slave detected a parity error reading its own memory. Usually indicates actual hardware degradation. Replace the device.
Exception 0A - Gateway Path Unavailable
Returned only by Modbus gateways (TCP-to-RTU bridges, usually). The gateway can't reach the downstream serial network at all. Check the cable from gateway to bus, check the gateway's status LED, check the gateway's own diagnostic page.
Exception 0B - Gateway Target Failed to Respond
The gateway reached the serial network but the specific slave you addressed didn't respond. Different cause from 0A: the bus is live but this slave is silent. Check unit ID, check bus addressing, check whether the slave is powered.
Triage flowchart
When you don't know which exception you're looking at, run the following questions in order:
Wrap-up
Exceptions are the most useful diagnostic information Modbus gives you. Read them carefully, capture them on the wire, and most of your field tickets resolve before lunch. If you'd like the full triage in one PDF you can keep on your laptop, the Modbus Debugging Field Manual covers every exception in much more depth, with worked examples from real plant work.