← All Posts

Modbus Exception Codes Explained: Illegal Function, Data, Address

You sent a read, and instead of data the slave replied with a short, blunt error. That reply is a Modbus exception response, and the exception code inside it tells you exactly what the slave rejected about your request. The good news: there are only eight of them, and four account for almost everything you will ever see.

This guide decodes each exception code, shows the wire format that distinguishes an error from a normal response, and gives the fix for each. It pairs with the function codes reference, exceptions are how the slave refuses a function code it cannot honour.

How to Spot an Exception Response

A normal Modbus response echoes the function code you sent. An exception response sets the high bit of that byte, your function code plus 0x80. The next and final byte is the exception code.

If you sent FC03 (0x03), an exception response begins with 0x83. If you sent FC10 (0x10), it begins with 0x90. A normal data response never has bit 7 set, so checking that single bit is the reliable way to separate data from error.

An exception frame is always exactly three payload bytes: unit ID, function code + 0x80, exception code. No data, no byte-count field. If your master shows a response shorter than expected, suspect an exception.

The Exception Codes

Code
Name
What the slave is telling you
01
Illegal Function
The function code is not supported. Wrong code for the table (FC03 on an input register), or the device does not implement that code at all.
02
Illegal Data Address
The address range is outside what the slave implements. Almost always an off-by-one addressing error or reading past the last register.
03
Illegal Data Value
The address is valid but the value or quantity is not, too many registers in one read, or a write value outside the permitted range.
04
Slave Device Failure
The slave understood the request but failed internally, overrun fault, watchdog reset, or a hardware problem. Retry; if it persists, the device needs attention.
05
Acknowledge
Request received but the operation takes a long time (e.g. a calibration command). The slave will be busy, poll for completion.
06
Slave Device Busy
The slave is mid-operation and cannot serve the request right now. Retry after a short delay. Common during long writes.
08
Memory Parity Error
The slave detected a parity fault reading its own non-volatile memory. Rare; usually a failing EEPROM or a firmware bug.
0A
Gateway Path Unavailable
(TCP/gateways only) The gateway could not establish a path to the target slave behind it. The downstream device is offline or mis-addressed.
0B
Gateway Target No Response
(TCP/gateways only) The gateway reached the target slave but got no reply. Downstream timeout, wrong baud, dead device, or bus collision.

Code 01: Illegal Function

The slave received a function code it does not support. The classic trigger is a table mismatch: you read an input register (a 3xxxx address) with FC03, which is the holding-register read. The slave knows that address lives in the input-register table and refuses the holding-register code.

Fix: match the function code to the data table. Holding registers → FC03, input registers → FC04, coils → FC01, discrete inputs → FC02. The address prefix tells you which, see Modbus addressing explained. Code 01 also appears on devices that only implement a subset: a power meter that reads with FC04 but has no write capability will return 01 to any FC06/FC16.

Code 02: Illegal Data Address

This is the one you will see most. The function code and quantity are fine, but the start address, or start-plus-quantity, falls outside the range the slave actually implements.

The dominant cause is the off-by-one: you typed the PLC address (40321) and your tool sent it verbatim as the protocol address, pointing one register past where you meant. The second cause is reading past the end of the device's map, a meter that exposes 200 registers and you read 40001 quantity 250, the last 50 do not exist.

Fix: confirm your tool's addressing mode and subtract 1 if it sends PLC addresses raw (full method in the addressing guide). Then verify the register exists in the device map for your firmware revision, vendors move and add registers between revisions, and a map for v1.2 will throw 02s on v2.0 firmware.

Code 02 ≠ the device is broken. It means your request points somewhere the device does not have a register. 90% of the time the device is fine and your address is wrong. Fix the address before blaming the hardware.

Code 03: Illegal Data Value

The address range is valid, but the value or quantity is not. The two triggers:

  • Too many registers in one read. You requested 200 registers but the device caps reads at 125. Split the read.
  • Out-of-range write value. You wrote a setpoint the register does not accept, 0xFFFF to a register that takes 0–100, or a negative to an unsigned field. Check the register's documented min/max.

Fix: reduce the read quantity (batch in groups of 100–125) or correct the write value. Code 03 on a read almost always means "you asked for too much in one frame."

Code 04: Slave Device Failure

This is the one that actually points at the slave, not your request. The slave understood the request but could not complete it, an internal overrun, a watchdog reset, a communication buffer fault, or a hardware problem. It is the catch-all "something broke on my end" code.

Fix: retry once. If it is intermittent, suspect electrical noise, ground loops, or a power-supply issue on the device. If it is constant for one register but not others, that register's backing hardware may be faulty. Persistent 04s on a previously-working device usually mean the device needs a power cycle or firmware attention.

Codes 05 and 06: Busy

These are not really errors, they are "try again." Code 05 (Acknowledge) means the slave accepted a long-running command (like a calibration) and is processing it. Code 06 (Slave Device Busy) means the slave is mid-operation and cannot serve you right now. Both are a request to back off and retry. Implement a retry loop with a short delay; these clear on their own.

Codes 0A and 0B: Gateway Errors (TCP Only)

These only appear with Modbus TCP gateways and serial-line converters, a TCP master talking to RTU slaves through a gateway. Code 0A (Gateway Path Unavailable) means the gateway could not build a route to the target unit ID; the downstream port or sub-network is down. Code 0B (Gateway Target No Response) means the gateway reached the slave but the slave never replied, the classic RTU bus problem (wrong baud, wrong unit ID, dead device, bus collision) surfaced through the TCP layer.

Fix: check the gateway's downstream wiring and the unit ID mapping. Code 0B downstream is really an RTU problem, see the RTU troubleshooting guide.

No Response at All: The Silent Exception

Not every error comes back as an exception code. The Modbus spec says a slave should stay silent on a CRC error, a framing error, or a request addressed to a different unit ID. So the most common "error" in the field is no response at all, your master times out waiting. That is not an exception code; it is a bus problem. Before chasing exception codes, confirm the device responds to anything: read a known register with a known tool. No reply means cabling, baud, parity, unit ID, or bus loading, start with RTU troubleshooting.

A Troubleshooting Order

  1. No response at all → bus-level problem (cable, baud, parity, unit ID, termination). Not an exception.
  2. Exception 02 → addressing. Check 0-based vs 1-based mode, subtract 1, verify the register exists in your firmware's map.
  3. Exception 01 → wrong function code for the table. FC03 vs FC04 is the usual culprit.
  4. Exception 03 → too many registers requested, or an out-of-range write value.
  5. Exception 04 → the slave itself is faulting. Retry; if persistent, hardware/power issue.
  6. Exception 06 / 05 → busy. Retry after a delay.
  7. Exception 0B → gateway downstream (RTU) not responding. Treat as an RTU bus problem.

Frequently Asked Questions

What does Modbus exception code 02 mean?

Exception code 02 is Illegal Data Address. The function code and quantity are valid, but the start address or start-plus-quantity falls outside the range the slave implements. The most common cause is an off-by-one addressing error. It also happens when you read past the last register a device exposes, or when the device map does not match the firmware revision.

What does Modbus exception code 01 mean?

Exception code 01 is Illegal Function. The slave received a function code it does not support, most often FC03 sent to an input register, or a write code sent to a read-only register. Switch to the correct function code for the data table you are targeting.

What does Modbus exception code 03 mean?

Exception code 03 is Illegal Data Value. The address range is valid but the value or quantity is not, typically you requested more registers than the device allows in one frame (often capped at 125), or wrote a value outside the permitted range. Reduce the read quantity and retry.

How do I know if a Modbus response is an exception?

An exception response sets the high bit of the function-code byte: the slave echoes your function code plus 0x80. If you sent FC03 (0x03), an exception response starts with 0x83. The next byte is the exception code. A normal response never has the high bit set.

See Every Exception in Plain Text

MacTools Modbus Poll decodes exception responses inline, you see "Illegal Data Address (0x02)" next to the frame, not a raw hex blob. Capture the traffic, filter by TX/RX, and hand the export to the device vendor as proof. Stop guessing what the slave refused.

Get Modbus Poll

Further Reading