How to Read Modbus 30001 vs 40001 Registers
A vendor manual lists a value at 30017 and your poll returns an exception, or worse, a plausible but wrong number. This is one of the most common Modbus mapping mistakes: reading a 3xxxx input register as if it were a 4xxxx holding register, or the reverse. The leading digit of the classic register number is not decoration - it names which of the four Modbus tables the value lives in, and each table is read with its own function code. This guide shows how to read the prefix, pick the correct function, and strip the number down to the address that actually goes on the wire.
Read 30001 vs 40001 registers in one line: The leading digit of a Modbus register number names its table: 3xxxx is an input register read with function code 04, and 4xxxx is a holding register read with function code 03. To read 30017, use FC04 and send offset 16 on the wire; to read 40017, use FC03 and send offset 16. The prefix is a naming convention, not part of the wire address, so drop the leading digit and subtract one to get the offset.
Read the Leading Digit to Identify the Table
Modbus exposes four data tables, and the traditional five- or six-digit register number encodes which table a value belongs to in its leading digit. A number beginning with 3, like 30001, is an input register: a sixteen-bit read-only word, usually a measurement the device produces. A number beginning with 4, like 40001, is a holding register: a sixteen-bit read-write word, usually a setpoint or general-purpose value. Numbers beginning with 0 and 1 are the single-bit coil and discrete-input tables. If you have not internalized these four, the definition of Modbus register types lays them out before you build any poll.
The practical consequence is that 30001 and 40001 are not the same value read two ways - they are two entirely different storage locations that happen to share the offset zero within their own tables. A flow computer can perfectly legitimately expose a live flow rate at input register 30001 and a totalizer preset at holding register 40001, and reading one when you meant the other returns a completely unrelated number with no error to warn you. So the first move when you open a register map is to note the leading digit of every point and sort your tags by table before you touch a function code.
Pick the Function Code That Matches the Table
Each table has a dedicated read function, and picking the wrong one is where the exception appears. Input registers (3xxxx) are read with function code 04. Holding registers (4xxxx) are read with function code 03. There is no overlap and no fallback: a device that maps a value only as an input register will typically reject an FC03 read of that address, because in the holding-register table that address may not exist. The distinction between the two reads is worth understanding in its own right, covered in the explainer on FC04 input register vs FC03 holding register.
In a SCADA driver this choice is usually a per-tag setting, sometimes labeled by function code and sometimes by table name. If your tool lets you type the raw register number with its prefix, it may pick the function for you - but only if you enter the prefix. Type 30017 and the driver reads FC04 offset 16; type 17 with no prefix and the driver falls back to its default table, which is almost always holding registers, and you silently read the wrong location. When a tag returns an illegal data address exception the moment you enable it, the mismatched function code is the first thing to check.
Strip the Prefix to Get the Wire Offset
Once the table and function are right, the last step is turning the human register number into the address the master actually transmits. Drop the leading digit that named the table, then subtract one, because the wire address is zero-based while the register number is one-based. So input register 30017 becomes offset 16 read with FC04, and holding register 40018 becomes offset 17 read with FC03. This subtraction is the same off-by-one that trips people on holding registers, explained fully under Modbus 40001 vs 0-based addressing.
The trap specific to the 3xxxx and 4xxxx split is doing the offset math but forgetting the function code, or getting the function right but keeping the prefix in the offset. If you send offset 30016 instead of 16, you either overrun the device's address space and get an exception, or you land on a real but wrong register. The clean procedure is: read the leading digit, choose FC03 or FC04 from it, then compute the offset from the remaining digits minus one. Do those three in order for every tag and the 3xxxx-versus-4xxxx confusion disappears.
Worked Example: One Value in Each Table
Suppose a device documents a flow rate at 30025 and a flow setpoint at 40025. Here is the full translation for both.
| Documented number | Table | Function code | Wire offset |
|---|---|---|---|
| 30025 (flow rate) | Input register (read-only) | FC04 | 24 |
| 40025 (flow setpoint) | Holding register (read-write) | FC03 to read, FC06 or FC16 to write | 24 |
Notice that both land on wire offset 24 - identical offsets in two different tables. That is exactly why the leading digit and the function code, not the offset, are what keep them apart. Reading offset 24 with FC03 gives you the setpoint; reading offset 24 with FC04 gives you the flow rate; and only the prefix told you which function to use.
If a device has just one of the two - only an input-register map, say - the mistake is subtler, because there is no competing value to make the error obvious. You read FC03 offset 24, the device rejects it or returns whatever happens to sit at holding offset 24, and nothing flags the tag as wrong. That is why the discipline of reading the leading digit first, before you ever type an offset, matters even on simple devices with a single table.
Frequently Asked Questions
Is 30001 the same as 40001 in Modbus?
No. 30001 is the first input register, a read-only measurement read with function code 04, and 40001 is the first holding register, a read-write value read with function code 03. They share the offset zero but live in two separate tables, so reading one when you meant the other returns an unrelated value or an exception. The leading digit tells you which table and which function code to use.
What function code do I use to read a 30001 register?
Function code 04, read input registers. The 3xxxx prefix names the input-register table, which is always read with FC04. Reading a 3xxxx register with FC03 targets the holding-register table instead and usually returns an illegal data address exception or a wrong value. Set the read function per tag to match the leading digit of each register number.
Do I subtract one from a 30001 register address?
Yes, after dropping the leading 3 you subtract one to reach the zero-based wire offset, so 30001 is offset 0 and 30017 is offset 16, both read with FC04. The leading digit only selects the table and function code and is never sent on the wire. Forgetting the subtraction produces the classic off-by-one; keeping the prefix in the offset produces an out-of-range address.
Sources and verification
This page references the protocol specifications published by the organizations below. Editions, product capabilities, and documentation change over time - confirm current requirements and specifications directly with the source.
- Modbus Application Protocol Specification - Modbus Organization
Merobix is not affiliated with, endorsed by, or sponsored by these organizations; their names are used only to identify the standards and products discussed.
Automation services
Need help turning this into a working system?
Merobix integrates SCADA, programs Allen-Bradley and Siemens PLCs, and designs and fabricates industrial control panels.
Meeting requests are reviewed before confirmation.