When commissioning Modbus RTU serial links or Modbus TCP industrial Ethernet networks, receiving a response with the high bit set on the function code indicates an exception. While Exception 01 means the slave doesn't support the command and Exception 02 means the requested register address is invalid, Exception Code 03 (Illegal Data Value) indicates that the address is acknowledged, but the contents of the data field violate protocol rules or device limits.
In this technical engineering guide, we break down the exact wire-level mechanics of Modbus Exception 03, identify the 5 most common developer and PLC programmer errors, inspect raw hex packet traces, and demonstrate how to test and isolate Exception 03 errors using Modbus Slave Simulator.
What is Modbus Exception Code 03?
According to the official Modbus Application Protocol Specification V1.1b3 (Section 7):
"A value contained in the query data field is not an allowable value for server (or slave). This indicates a fault in the structure of the remainder of a complex request, such as that the implied length is incorrect. It specifically does NOT refer to data items that have value outside expected ranges, unless the device specification dictates otherwise."
When a slave device encounters an illegal data value, it takes the master's function code, adds 0x80 (setting the most significant bit), and appends exception code 0x03:
| Direction | Frame Component | Hex Example | Description |
|---|---|---|---|
| Master → Slave | Function Code | 0x03 |
Read Holding Registers request |
| Master → Slave | Data Field | 0x00 0x01 0x00 0x80 |
Start Address: 1, Quantity: 128 registers (exceeds limit!) |
| Slave → Master | Error Function Code | 0x83 |
0x03 + 0x80 indicates error |
| Slave → Master | Exception Code | 0x03 |
ILLEGAL DATA VALUE |
The 5 Most Common Causes of Exception Code 03
1. Quantity of Registers Exceeds Maximum Protocol Limits
The standard Modbus RTU Application Data Unit (ADU) has a strict maximum length of 256 bytes. In a Read Holding Registers response (FC 03), each register takes 2 bytes, plus 1 byte for Slave Address, 1 byte for Function Code, 1 byte for Byte Count, and 2 bytes for CRC:
Max Registers = (256 - 5 bytes overhead) / 2 = 125.5 → 125 registers max
If your master poll requests 126 or more holding registers (or input registers via FC 04) in a single transaction, the slave cannot construct a response that fits into a standard Modbus packet. A properly implemented slave must reject the request with Exception 03.
Similarly, for discrete coils (FC 01) and inputs (FC 02), the maximum allowable quantity in one query is 2,000 items (0x07D0). Exceeding 2,000 items instantly triggers Exception 03.
2. Byte Count vs Quantity Mismatch in Multi-Register Writes (FC 15 & FC 16)
When writing multiple coils (FC 15) or multiple holding registers (FC 16), the request frame contains both a Quantity field and an explicit Byte Count field:
- For FC 16:
Byte Count must equal Quantity × 2. - For FC 15:
Byte Count must equal ceil(Quantity / 8).
If you specify Quantity = 2 registers, but your software driver writes Byte Count = 2 instead of 4, the slave's deserializer detects that the declared quantity does not match the byte payload length. The slave halts parsing and returns Exception Code 03.
3. Non-Standard Values for Single Coil Writes (FC 05)
When executing Function Code 05 (Write Single Coil), the Modbus standard does not accept a simple boolean 1 or 0 in the register word. Instead, it mandates strict two-byte constants:
- ON state:
0xFF00(decimal 65280) - OFF state:
0x0000(decimal 0)
If a custom Python script or SCADA driver transmits 0x0001, 0x0100, or 0xFFFF to activate a relay coil, compliant industrial RTUs and PLC slave stacks reject the packet with Exception Code 03 because 0x0001 is an invalid data value for FC 05.
4. Write Values Outside Allowed Engineering Range
Many smart transmitters, variable frequency drives (VFDs), and power meters perform semantic boundary checking on write operations. For example:
- A PID temperature controller allows setpoints between
0°Cand200°C. If your master writes350, the device rejects the parameter with Exception 03. - A VFD frequency setpoint allows
0.00 Hzto60.00 Hz. Writing7500(75.00 Hz) triggers Exception 03. - Modbus communication parameters (baud rate selector register): Valid values are
1 (9600),2 (19200),3 (38400). Writing7triggers Exception 03.
5. Writing 32-Bit Float/Double Values Across Misaligned Register Quantities
Modern industrial instruments store 32-bit floating-point numbers (IEEE 754) and 32-bit signed integers across two 16-bit Modbus registers. When writing to a 32-bit float register using FC 16, the master must write an even quantity of 2 registers (4 bytes).
If an engineer accidentally configures a single-register write (Quantity = 1) targeting the first half of a floating-point variable, the slave detects an incomplete data structure and replies with Exception Code 03.
Wire-Level Packet Traces: Analyzing Exception 03
Scenario A: Read Request Exceeding Maximum Limit (128 Registers)
Master Request:
[01] [03] [00 00] [00 80] [45 E2]
| | | | |
| | | | +-- CRC-16 Checksum
| | | +---------- Quantity: 128 (0x0080) > 125 max!
| | +------------------ Start Address: 0x0000 (Holding Register 40001)
| +------------------------- Function Code: 0x03 (Read Holding Registers)
+------------------------------ Slave ID: 1
Slave Exception Response:
[01] [83] [03] [01 31]
| | | |
| | | +-- CRC-16 Checksum
| | +--------- Exception Code: 0x03 (ILLEGAL DATA VALUE)
| +-------------- Error Code: 0x83 (0x03 + 0x80)
+------------------- Slave ID: 1
Scenario B: Single Coil Write with Non-Standard Value (0x0001)
Master Request:
[02] [05] [00 0A] [00 01] [6C 38]
| | | | |
| | | | +-- CRC-16 Checksum
| | | +---------- Invalid Value: 0x0001 (Must be 0xFF00 or 0x0000)
| | +------------------ Coil Address: 0x000A (Coil 11)
| +------------------------- Function Code: 0x05 (Write Single Coil)
+------------------------------ Slave ID: 2
Slave Exception Response:
[02] [85] [03] [02 61]
| | | |
| | | +-- CRC-16 Checksum
| | +--------- Exception Code: 0x03 (ILLEGAL DATA VALUE)
| +-------------- Error Code: 0x85 (0x05 + 0x80)
+------------------- Slave ID: 2
Step-by-Step Troubleshooting Checklist
- Verify Request Quantity: Ensure that your read query does not ask for more than 125 holding registers (FC 03) or 125 input registers (FC 04). If you need 500 registers, split your query into multiple smaller chunks (e.g., 4 requests of 125 registers each).
- Check Byte Count in Multi-Writes: When using FC 15 or FC 16, verify your packet builder math. Ensure that
Byte Count = Quantity × 2for registers andceil(Quantity / 8)for coils. - Inspect Coil Write Constants: If using FC 05, ensure your master sends
0xFF00for ON and0x0000for OFF. Avoid sending integer1. - Review Device Register Map Manual: Check the vendor documentation for min/max limits on writable parameters. If a register represents an enum or calibration threshold, ensure your write value falls strictly inside the documented boundaries.
- Ensure Even Register Quantities for 32-Bit Types: When writing Float32 or Int32 variables, always configure your master block size to 2 registers (4 bytes).
Diagnosing Exception 03 with ModbusSimulator
Troubleshooting Exception 03 against a physical PLC on a live production line can be dangerous or disruptive. Using Modbus Slave Simulator allows you to safely isolate and reproduce exception behavior in minutes:
Launch ModbusSimulator on Windows, configure Slave ID 1, and enable the real-time Hex Traffic Monitor. Send your SCADA or PLC driver polls to the simulator. The live inspector clearly highlights packet length violations, illegal coil values, and out-of-range parameters before you connect to real field instruments.
Simulate and Debug Modbus Communications Instantly
Test Modbus RTU and TCP master/slave communications without hardware. Inspect raw hex packets, simulate multi-slave networks, and verify exception handling in real time.
Summary: Modbus Exception Codes Quick Reference
| Code | Exception Name | Core Trigger | Recommended Action |
|---|---|---|---|
| 01 (0x01) | Illegal Function | Slave doesn't support the requested function code | Switch to supported FC (e.g. FC 16 instead of FC 06) |
| 02 (0x02) | Illegal Data Address | Register address doesn't exist in slave memory | Check 0-based vs 1-based offset and register map |
| 03 (0x03) | Illegal Data Value | Quantity exceeds limits or write payload out of range | Limit read quantity to ≤ 125 registers, check FC 05 coil hex values |
| 04 (0x04) | Slave Device Failure | Unrecoverable hardware or memory fault inside slave | Power cycle instrument, inspect field wiring and sensor status |
Related Engineering Resources
- Modbus Exception Code 01 (Illegal Function) Troubleshooting Guide
- Modbus Exception Code 02 (Illegal Data Address) Troubleshooting Guide
- Complete Guide to Modbus Function Codes (FC 01 through FC 16)
- RS-485 Serial Port Troubleshooting for Modbus RTU
- Modbus Slave Simulator Software for Windows
- Modbus TCP Server & Client Simulator