When a Modbus device receives a request but cannot carry it out, it sends an «exception response». Getting one means wiring, baud rate and slave ID are fine and the request itself does not fit the device — easier to fix than a timeout. This follows chapters 6 (state diagrams per function) and 7 (exception responses) of the MODBUS Application Protocol Specification V1.1b3.
When you get an exception — and when you do not
| What the device received | Its reaction (spec chapter 7) |
|---|---|
| A request without communication error that it can handle | Normal response |
| Nothing, because of a communication error | No response → the master times out |
| A request with a parity, CRC or LRC error | No response → the master times out |
| A valid request it cannot handle (non-existent address…) | Exception response |
So a request with a bad CRC never gets an exception. If all you see are timeouts, the problem is on the communication side — see the Modbus no-response checklist.
Shape: function code + 0x80, then one exception byte
request 01 03 00 60 00 05 85 D7 ← slave 1, 5 holding registers from 96 response 01 83 02 C0 F1 ← 83 = 03 + 80, exception code 02
A normal response echoes the function code; an exception response sets its most significant bit (adds 0x80). All function codes are below 0x80, so a second byte of 0x80 or more means an exception. RTU adds a 2-byte CRC; TCP sends only «83 02» after the 7-byte MBAP header.
| Request function | Exception function |
|---|---|
| 01 Read Coils | 81 |
| 02 Read Discrete Inputs | 82 |
| 03 Read Holding Registers | 83 |
| 04 Read Input Registers | 84 |
| 05 Write Single Coil | 85 |
| 06 Write Single Register | 86 |
| 0F Write Multiple Coils | 8F |
| 10 Write Multiple Registers | 90 |
| 17 Read/Write Multiple Registers | 97 |
Exception codes (spec chapter 7)
| Code | Name | Meaning |
|---|---|---|
| 01 | ILLEGAL FUNCTION | The function code is not allowed: not implemented in this device, or the device is in the wrong state (e.g. unconfigured) |
| 02 | ILLEGAL DATA ADDRESS | The address does not exist; more precisely, the combination of start address and quantity is out of range |
| 03 | ILLEGAL DATA VALUE | A value in the request's data field is not allowed — the structure of the request, such as a quantity or byte count, is wrong |
| 04 | SERVER DEVICE FAILURE | An unrecoverable error occurred while performing the action |
| 05 | ACKNOWLEDGE | For programming commands: accepted, but it will take long (sent to prevent a master timeout) |
| 06 | SERVER DEVICE BUSY | Busy with a long-duration command; retransmit later |
| 08 | MEMORY PARITY ERROR | Parity error in memory while reading a file record (functions 20/21) |
| 0A | GATEWAY PATH UNAVAILABLE | The gateway could not allocate a path from input to output port — misconfigured or overloaded |
| 0B | GATEWAY TARGET DEVICE FAILED TO RESPOND | No response from the device behind the gateway — usually it is not on the network |
Codes 07 and 09 are not defined in this edition (V1.1b3). If you see them, look for the device's own error table in its manual.
The order a device checks: 01 → 03 → 02 → 04
The state diagrams in chapter 6 check read and write requests (functions 01–06, 0F, 10) in the same order, so the exception code also tells you how far the request got.
| Step | Check | On failure |
|---|---|---|
| 1 | Is the function code supported? | 01 |
| 2 | Is the quantity in range — 1–125 (0x007D) for 03/04, 1–2000 (0x07D0) for 01/02, 1–123 (0x007B) for 10, 1–1968 (0x07B0) for 0F; for 05, is the value 0000 or FF00? | 03 |
| 3 | Are the start address and start + quantity inside the device's range? | 02 |
| 4 | Did the read or write actually succeed? | 04 |
So a 03 means the function is supported and the request failed on the quantity (or value) before the address was even checked. The quantities are the specification maximums; devices may set lower limits.
02: address range — the specification's example
Chapter 7 uses a device with 100 registers (0–99). Reading 4 registers from 96 (96–99) works; reading 5 from 96 fails entirely with exception 02 because register 100 does not exist. «01 03 00 60 00 05» above is exactly that request (0x60 = 96). If any part is out of range nothing is returned, so read contiguous blocks only.
- Mixing 0-based addresses with 1-based (40001) notation shifts by one and easily pushes the last register out of range — see the Modbus address notation guide.
- Where the manual's register table has gaps, many devices return 02 when a read spans the gap.
- If FC03 returns 02, check the manual's function code column — the value may be an input register (FC04).
03: values — what the specification does and does not say
The specification defines 03 as «a fault in the structure of the remainder of a complex request, such as that the implied length is incorrect», and adds that it «specifically does NOT mean that a data item submitted for storage in a register has a value outside the expectation of the application program». Whether a device rejects an out-of-range write with 03, ignores it or clamps it is in its manual.
04 and 06: device state
04 is an internal processing error — check the device's status display and the error section of its manual. 06 (busy) means retry the same request later; it also appears when requests come too close together, so increase the delay between requests. Other exceptions return the same answer on retry, so they are not worth retrying.
0A and 0B: behind a gateway
If a Modbus TCP ↔ RTU gateway returns 0A or 0B, the TCP link from the PC to the gateway works. 0B means the serial device behind it did not answer — check the unit ID (= serial slave ID), baud rate, parity and RS-485 wiring. 0A points to the gateway's port and routing settings.
Examples from device manuals
- 01: the Rootech Accura 3300E supports only functions 03, 06 and 16 — any other (e.g. 04) is an «illegal function» for it.
- 03: devices whose per-request limit is below the specification's 125 — 124 on the LS ELECTRIC GIMAC1000, 31 with FC03 on the Hanyoung Nux VX.
- Writes only fail: the Hanyoung Nux LC ships with communication write protection (CWP) ON and rejects writes with an exception until it is turned OFF on the front panel (manual pp. 31, 34).
In PortDock
- «Modbus Frame Decoder» web tool: paste the received bytes to see whether it is an exception and which code (RTU and TCP).
- Modbus Master: the traffic log names each exception and every table counts them. Exception responses are not retried.
- Modbus Slave: «fault injection» returns exceptions on purpose so you can see how your master or HMI handles them.
Published 2026-10-23