Modbus registers: word, bit, real, and the Illegal Data Address error
A Modbus point is configured. The address is correct, the wiring works, the PLC responds to other requests. And yet, that point never returns anything. No error shown to the operator, no alarm. Just a value that stays blank.
It's Modbus TCP's most misleading symptom: a bad read doesn't break anything noisily. It fails silently, at the protocol level, and that silence is easy to mistake for a wiring or PLC problem.
The 4 tables, and why they don't forgive mistakes
Modbus organizes its memory into four distinct tables. Each has its own address space and its own function code:
| Table | Function code | Access | Content | |---|---|---|---| | Coil | 01 (read), 05/15 (write) | Read/write | A bit, discrete output | | Input status (discrete input) | 02 | Read-only | A bit, discrete input | | Holding register | 03 (read), 06/16 (write) | Read/write | A 16-bit word | | Input register | 04 | Read-only | A 16-bit word |
Two tables share the same data type (Holding and Input register are both 16-bit words), and two share the same access mode (Coil and Holding are both writable). Nothing stops you from picking the wrong table for an address that, elsewhere, genuinely exists on the PLC.
The result of that mix-up is an Illegal Data Address error. It says exactly one thing: "this table, at this address, for this function code, doesn't exist." It doesn't say which table to use instead. And on many master-side implementations, that error gets logged to a technical log nobody checks day to day. The operator, meanwhile, just sees a blank field on their dashboard.
Vendor documentation isn't always enough to settle it either: two PLCs from the same range can expose an identical variable on different tables depending on firmware version. The reliable method stays testing all four function codes against the suspect address before concluding it's a fault.
A float that spans two registers
A Modbus register is 16 bits. A single-precision IEEE754 float is 32. The consequence is mechanical: any decimal value (a temperature, a power reading, a flow rate) occupies two consecutive registers, never just one.
On a real register table seen during a technical exchange, an energy
value in kWh was split like this: register 40010 carried the
high-order 16 bits, register 40011 the low-order 16 bits. Reading only
40010 and interpreting it as an integer gave a number with no relation
to the actual measurement.
This split has a name: word order (or byte order depending on the implementation), and it isn't universally standardized. Two conventions coexist in the field:
- high-first (big-endian at the word level): the first register read carries the high-order bits.
- low-first (little-endian at the word level): the reverse — the second register carries the high-order bits.
Neither is more "standard" than the other. Every PLC enforces its own, and nothing in a raw Modbus read lets you guess which without documenting or testing it: a value recombined the wrong way still looks like a perfectly plausible number — just a wrong one.
A single bit inside a whole word
A third, more subtle trap: a 16-bit register doesn't always carry a
single value. On that same register table, one word grouped several
logical statuses together, each on its own bit. For example, bit 3 of
register 30 corresponds to a "valve DP-101 open" status.
Reading that register as a whole word returns a number (say, 8) that means nothing until it's broken down into bits. Two different measurement points can therefore share the exact same Modbus address, each with a different bit. A tool that only handles one format per address loses half of it.
Nodal treats these three cases as three different read formats for the
same point: word (the whole register, the default behavior), bit (a
specific bit within a word), and real (a float spanning two registers,
with the word order chosen explicitly). The format is configured once
per point, and the agent applies the right decoding on every read.
Check before suspecting the hardware
Faced with a silent Modbus point, the order of checks that avoids wasting time on the wrong suspect:
- Confirm the address genuinely exists in the target table — in the PLC's actual response, not just in the documentation.
- Test all four function codes against that address rather than assuming the vendor documentation is up to date.
- If a value comes back but looks off, check whether it's a float spanning two registers before suspecting a calibration issue.
- If a number comes back but doesn't match anything known, check whether the register encodes several distinct bits rather than a single value.
In the vast majority of cases, a Modbus point that returns nothing has no hardware fault. It has an address sent to the wrong table, or a value recombined incorrectly. The diagnosis takes five minutes once you know where to look.
Nodal handles all three formats (word, bit, real) at the gateway level, with the right word order configured once per point.
Frequently asked questions
- What does "Illegal Data Address" mean in Modbus?
- The Modbus master requested an address or table the PLC doesn't recognize for the function used. It's a protocol error, not a hardware fault: the most common cause is a function code that doesn't match the point's actual table (for example, reading a Holding register address that only exists as an Input register).
- How do you read a 32-bit float from a Modbus register?
- A 32-bit IEEE754 float occupies two consecutive registers (16 bits each). The two halves have to be recombined in the right order: high-first if the first register carries the high-order bits, low-first otherwise. PLCs don't all agree on this order — it has to be determined case by case.

Dayen Driss
CEO, Nodal
Founder of Nodal, where he builds the Edge gateway and the cloud platform.