A practical reference for engineers covering every Modbus exception code (01, 02, 03, 04, 05, 06, 08, 0A, 0B) — what each code means, what causes it, how to fix it, and how to identify exception responses in Wireshark
Introduction
When a Modbus master sends a request to a slave, four things can happen:
- The slave processes the request and returns a normal response
- The slave never receives the request (communication error) — no response, master times out
- The slave receives the request but detects a transmission error (CRC/LRC/parity) — no response
- The slave receives the request but cannot process it — returns an exception response
This article covers case 4 — the exception responses. Every Modbus engineer needs to know what each exception code means and how to fix it. A wrong register address, wrong function code, or device state issue produces a specific exception code that tells you exactly what went wrong.
Table of Contents
1. How Modbus Exception Responses Work
When a slave cannot fulfill a request, it returns an exception response that tells the master what went wrong. The response uses the same connection, same Unit ID, but signals an exception in two ways:
- The function code is set to the original code with bit 7 (the high bit) set
- The data field contains a single byte: the exception code
Function Code Modification
The slave takes the original function code and adds 0x80 (128 decimal). This sets the high bit:
| Original Function Code | Exception Function Code | Meaning |
|---|---|---|
| 0x01 (1) | 0x81 (129) | Read Coils — exception |
| 0x03 (3) | 0x83 (131) | Read Holding Registers — exception |
| 0x04 (4) | 0x84 (132) | Read Input Registers — exception |
| 0x06 (6) | 0x86 (134) | Write Single Register — exception |
| 0x10 (16) | 0x90 (144) | Write Multiple Registers — exception |
| 0x0F (15) | 0x8F (143) | Write Multiple Coils — exception |
When you see a function code ≥ 0x80, the response is an exception. The master must check this bit before parsing the response data.
2. The Exception Response Frame
Modbus TCP Exception Response
| Field | Bytes | Example | Description |
|---|---|---|---|
| MBAP Header | 7 | 00 01 00 00 00 03 01 | Transaction ID, Protocol ID, Length, Unit ID |
| Function Code | 1 | 83 | Original function code + 0x80 |
| Exception Code | 1 | 02 | The exception code (1 byte) |
Total exception response size: 9 bytes (TCP).
Modbus RTU Exception Response
| Field | Bytes | Example | Description |
|---|---|---|---|
| Slave Address | 1 | 01 | Unit ID |
| Function Code | 1 | 83 | Original function code + 0x80 |
| Exception Code | 1 | 02 | The exception code |
| CRC | 2 | C0 F1 | CRC-16 |
Total exception response size: 5 bytes (RTU).
Example: Exception Code 02 in Response to FC 03
Master sends Read Holding Registers request to a non-existent register address. Slave responds:
TCP Response: 00 01 00 00 00 03 01 83 02
Exception code: 02 (Illegal Data Address)
Function code with high bit set (0x83 = 0x03 + 0x80)
3. Quick Reference: All Modbus Exception Codes
Verified against the Modbus Application Protocol V1.1b specification (Section 7, Table at end of standard):
| Code (Hex) | Code (Dec) | Name | When It Occurs |
|---|---|---|---|
| 01 | 1 | Illegal Function | Function code not supported by the slave |
| 02 | 2 | Illegal Data Address | Register address not valid for the slave |
| 03 | 3 | Illegal Data Value | Value or quantity in the request is not allowed |
| 04 | 4 | Slave Device Failure | Unrecoverable error during the requested action |
| 05 | 5 | Acknowledge | Slave accepted the request — long processing time required |
| 06 | 6 | Slave Device Busy | Slave is processing a long-duration command — try again later |
| 08 | 8 | Memory Parity Error | Memory consistency check failed (FC 20/21 with reference type 6) |
| 0A | 10 | Gateway Path Unavailable | Gateway cannot allocate a path |
| 0B | 11 | Gateway Target Device Failed to Respond | Gateway received no response from the target |
Codes 07 and 09 are not assigned in the standard.
4. Exception Code 01 — Illegal Function
Hex: 0x01 | Decimal: 1 | Name: ILLEGAL FUNCTION
The function code received in the query is not supported by the slave.
Common Causes
- The slave does not implement this function code (e.g., master sends FC 03 to a coil-only device)
- The function code is from a newer Modbus version not supported by older firmware
- The slave is in a state that does not allow this function (e.g., listen-only mode does not allow writes)
- The function code is reserved or vendor-specific and not recognized
Example Scenarios
- Master sends FC 03 (Read Holding Registers) to a slave that only has discrete inputs → Exception 01
- Master sends FC 23 (Read/Write Multiple Registers) to a basic slave that only supports FC 03 and FC 16 → Exception 01
- Master sends FC 43 (Encapsulated Interface) to an old slave → Exception 01
How to Fix
- Check the slave’s documentation for supported function codes
- Use a different function code that the slave supports
- Verify the slave is not in a special state (listen-only, configuration mode)
- For multi-vendor systems, always check supported function codes per device
5. Exception Code 02 — Illegal Data Address
Hex: 0x02 | Decimal: 2 | Name: ILLEGAL DATA ADDRESS
The data address received in the query is not valid for the slave. More specifically, the combination of starting address and quantity is invalid.
This is the most common Modbus exception in real systems.
Common Causes
- The starting register address does not exist on the slave
- The quantity of registers requested goes beyond the slave’s address range
- Off-by-one errors (Modbus PDU addressing is 0-based; many register maps document 1-based addresses)
- The address is correct but the slave’s mapping is different than the documentation
The Off-by-One Trap
In Modbus, register 40001 in the user-facing register map corresponds to PDU address 0.
| Register Map Address | PDU Address | Note |
|---|---|---|
| 40001 | 0 | First holding register |
| 40002 | 1 | Second holding register |
| 40100 | 99 | 100th holding register |
If a slave has 100 holding registers (40001–40100) and the master requests 6 registers starting at PDU address 96, the request covers PDU addresses 96–101. Address 100 and 101 do not exist → Exception 02.
Example Scenarios
- Master requests register 40050 (PDU 49), but the slave only has registers 40001–40010 → Exception 02
- Master requests 125 holding registers starting at register 40001, but the slave has fewer than 125 → Exception 02
- Master uses register address 1 thinking it is the first register, but on this slave the first register is address 0 → Exception 02
How to Fix
- Verify the register map in the slave’s documentation
- Check whether documentation uses 1-based or 0-based addressing
- Confirm the quantity is within the slave’s address range
- Use a Modbus simulator or
modpollto test addresses one by one
For a complete guide on register addressing, see: How to Read a Modbus Register Map
6. Exception Code 03 — Illegal Data Value
Hex: 0x03 | Decimal: 3 | Name: ILLEGAL DATA VALUE
A value contained in the query data field is not allowed for the slave. This indicates a fault in the structure of the request, not a problem with values that will be stored.
What This Code Does NOT Mean
This code does not mean a value being stored is out of range for the application. For example, writing a value of 10000 to a register that should hold 0–100 will not produce Exception 03 — that is application-level validation. Exception 03 means the Modbus request structure itself is malformed.
Common Causes
- The quantity field is 0 (you cannot read 0 registers)
- The quantity field exceeds the function code maximum (FC 03 max is 125 registers)
- For Write Multiple Coils (FC 15): quantity exceeds 1968
- For Write Multiple Registers (FC 16): quantity exceeds 123
- The byte count does not match the quantity (mismatch in FC 15 or FC 16)
- For FC 06 (Write Single Register): the value field has the wrong size
Function Code Quantity Limits
| Function Code | Max Quantity | Reason |
|---|---|---|
| FC 01 (Read Coils) | 2000 | Limit per request |
| FC 02 (Read Discrete Inputs) | 2000 | Limit per request |
| FC 03 (Read Holding Registers) | 125 | Limit per request |
| FC 04 (Read Input Registers) | 125 | Limit per request |
| FC 15 (Write Multiple Coils) | 1968 | Limit per request |
| FC 16 (Write Multiple Registers) | 123 | Limit per request |
How to Fix
- Verify the quantity in the request is within the function code limits
- Check that the byte count matches the quantity for write requests
- Split large requests into multiple smaller requests
7. Exception Code 04 — Slave Device Failure
Hex: 0x04 | Decimal: 4 | Name: SLAVE DEVICE FAILURE
An unrecoverable error occurred while the slave was attempting to perform the requested action.
Common Causes
- Internal slave hardware failure
- Memory error or corruption
- The slave failed to access the requested register due to internal logic error
- Hardware module not responding (e.g., I/O card disconnected from CPU)
- Sensor or output device behind the register is faulty
- For VFDs/drives: trying to write a parameter while the drive is in a forbidden state
Example Scenarios
- Master writes a setpoint to a VFD that is faulted → Exception 04
- Master reads a register mapped to a temperature sensor that is disconnected → Exception 04
- Master writes to a register on a slave with a corrupted memory bank → Exception 04
How to Fix
- Check the slave device for faults or error codes (LED, display, diagnostics)
- Reset or power-cycle the slave
- Check physical connections to I/O modules and sensors
- Review slave documentation for state-dependent register access
- If the error persists, the slave may need firmware repair or replacement
8. Exception Code 05 — Acknowledge
Hex: 0x05 | Decimal: 5 | Name: ACKNOWLEDGE
Specialized use in programming commands. The slave has accepted the request and is processing it, but the operation will take a long time. The slave returns this exception to prevent the master from timing out.
Common Causes
- Programming a slave (firmware update, configuration download)
- Long write operations to flash memory
- Calibration or initialization sequences
How the Master Should Respond
The master should:
- Wait an appropriate amount of time (depending on the operation)
- Send a Poll Program Complete message to check if the operation is finished
This exception is mainly used with vendor-specific programming function codes. Standard read/write operations should not produce this code.
9. Exception Code 06 — Slave Device Busy
Hex: 0x06 | Decimal: 6 | Name: SLAVE DEVICE BUSY
Specialized use in programming commands. The slave is currently processing a long-duration program command and cannot accept this request.
Common Causes
- Slave is being programmed by another master
- Slave is in a long initialization sequence
- Internal background task is using the resource the master wants to access
How the Master Should Respond
The master should retransmit the request later when the slave has completed the long-duration command. The master should not retransmit immediately — that will just trigger another Exception 06.
A reasonable strategy: wait at least 1 second before retrying.
10. Exception Code 08 — Memory Parity Error
Hex: 0x08 | Decimal: 8 | Name: MEMORY PARITY ERROR
Specialized use with function codes 20 (0x14) and 21 (0x15) with reference type 6. Indicates that the extended file area failed to pass a consistency check.
What This Means
Modbus FC 20 and FC 21 access record-based file data (extended memory areas). When the slave reads these records and discovers that internal consistency checks (parity, checksum) fail, it returns Exception 08.
Common Causes
- Memory corruption in the slave’s record/file storage
- Hardware issue affecting the memory bank used for files
- Storage media failure (in slaves that use external memory)
How to Fix
- Power-cycle the slave to refresh memory state
- Reload the file data from a backup
- If the slave supports it, re-initialize the affected memory area
- If the error persists, the slave hardware may be failing
This exception is rare — most Modbus systems do not use file record functions (FC 20/21).
11. Exception Code 0A — Gateway Path Unavailable
Hex: 0x0A | Decimal: 10 | Name: GATEWAY PATH UNAVAILABLE
Specialized use with gateways. The gateway cannot allocate an internal communication path between the input port and the output port to process the request.
Common Causes
- Gateway misconfiguration (no route from the master’s port to the target slave)
- All gateway internal channels are busy
- The target Unit ID is not configured in the gateway’s routing table
Example: Modbus TCP-to-RTU Gateway
A gateway connects a Modbus TCP master to RS-485 slaves. The master sends a request with Unit ID = 5. If the gateway’s configuration only knows about Unit IDs 1–3, it returns Exception 0A — there is no path to Unit ID 5.
How to Fix
- Check the gateway configuration for routing/path settings
- Verify the Unit ID in the request matches the gateway’s known slaves
- Reduce concurrent requests if the gateway is overloaded
- Check the gateway’s serial port configuration (baud rate, parity)
12. Exception Code 0B — Gateway Target Device Failed to Respond
Hex: 0x0B | Decimal: 11 | Name: GATEWAY TARGET DEVICE FAILED TO RESPOND
Specialized use with gateways. The gateway forwarded the request to the target slave but the target did not respond within the gateway’s timeout.
How This Is Different from a Standard Timeout
In a direct master-to-slave Modbus connection, no response means the master times out. With a gateway, the gateway itself notices the target is not responding and returns Exception 0B to the master. The master gets a quick error response instead of waiting for its full timeout.
Common Causes
- Target slave is offline or powered off
- Target slave is not connected to the gateway’s serial bus
- Wrong slave address
- Wiring problem on the RS-485/RS-232 side of the gateway
- Target slave is busy and not responding within the gateway timeout
How to Fix
- Verify the target slave is powered on
- Check the physical connection between the gateway and the slave
- Verify the slave address (Unit ID) configured on the slave matches the request
- Check the serial settings on both the gateway and the slave (baud rate, parity, stop bits)
- Increase the gateway’s response timeout if the slave is genuinely slow
- Use Wireshark on both sides of the gateway to identify where the request is failing
13. How to Identify Exception Responses in Wireshark
Wireshark decodes Modbus exception responses automatically. To filter for them:
Display Filters
| Filter | What It Shows |
|---|---|
modbus.func_code >= 128 | All exception responses (function code with high bit set) |
modbus.exception_code | Frames containing an exception code field |
modbus.exception_code == 1 | Illegal Function exceptions |
modbus.exception_code == 2 | Illegal Data Address exceptions |
modbus.exception_code == 3 | Illegal Data Value exceptions |
modbus.exception_code == 4 | Slave Device Failure exceptions |
modbus.exception_code == 11 | Gateway Target Failed to Respond (0x0B) |
What an Exception Looks Like in Wireshark
When you click on an exception response:
Modbus
.000 0011 = Function Code: Read Holding Registers (3)
[Exception]
Exception Code: Illegal data address (2)
The Info column shows:
Response: Trans: 1; Unit: 1, Func: 131: Read Holding Registers. Exception: Illegal data address
For more on Modbus Wireshark analysis, see: Wireshark for Modbus TCP
14. Common Causes and Fixes by Exception Code
| Code | Most Common Cause | Quick Fix |
|---|---|---|
| 01 | Wrong function code for this slave | Check supported function codes in slave docs |
| 02 | Off-by-one register address (0-based vs 1-based) | Verify register map; subtract 1 if using 40001-style addressing |
| 03 | Quantity exceeds function limit | For FC 03/04, max 125; for FC 16, max 123 |
| 04 | Slave hardware fault, faulted VFD, disconnected I/O | Check slave fault display, reset device |
| 05 | Long programming command in progress | Wait, then send Poll Program Complete |
| 06 | Slave busy with another command | Wait 1 second, retry |
| 08 | Memory consistency check failed (FC 20/21) | Power cycle, reload file data |
| 0A | Gateway has no path to target Unit ID | Check gateway routing/configuration |
| 0B | Target slave behind gateway not responding | Check power, wiring, baud rate, slave address |
15. Exception Codes vs Communication Errors
It is important to distinguish exception responses from communication errors:
| Type | What Happens | Master Response |
|---|---|---|
| Exception response | Slave returns a frame with function code + 0x80 and an exception code | Master parses the exception and reports it |
| No response (timeout) | Slave never replies — request lost or slave offline | Master times out after configured period |
| CRC/LRC error | Slave received frame with bad checksum — discards silently | Master times out |
| Parity error (RTU) | Serial transmission error — slave discards | Master times out |
An exception means the slave heard the request but cannot fulfill it. A timeout means the slave never heard the request (or the response was lost). These are very different problems requiring different troubleshooting approaches.
Summary
Modbus exception codes tell you exactly what went wrong with a request. The slave returns the original function code with bit 7 set (e.g., 0x83 instead of 0x03) followed by a single-byte exception code.
The key things to remember:
- Exception 02 (Illegal Data Address) is the most common — usually an off-by-one error or wrong register map
- Exception 01 (Illegal Function) — the slave does not support this function code
- Exception 03 (Illegal Data Value) — the request structure is malformed (quantity too high, byte count mismatch)
- Exception 04 (Slave Device Failure) — internal slave error, often hardware-related
- Exceptions 05 and 06 — only used with programming commands
- Exception 08 — only with FC 20/21 (file records)
- Exceptions 0A and 0B — only from gateways (path unavailable, target not responding)
- Codes 07 and 09 are not assigned in the standard
- An exception response means the slave heard the request — different from a timeout where the slave never responded
💡 Tip: Use the free Modbus Frame Decoder Tool to decode any Modbus frame byte by byte — including exception responses with the function code and exception code clearly identified.
For Modbus protocol fundamentals, see: Modbus Protocol Guide
For function code details, see: Modbus Function Codes Explained
For troubleshooting Modbus systems, see: Modbus Troubleshooting Guide for SCADA
