Modbus Register Offset: The 0-Based vs 1-Based Problem

TROUBLESHOOTINGUpdated Feb 20268 min read

Modbus register addressing is one of the most confusing aspects of the protocol — not because it's complicated, but because there are three different conventions used by documentation, tools, and the actual wire protocol, and they all disagree by 1.

Why It's Confusing

Imagine a device with holding registers starting at "address 1" according to its manual. Depending on which Modbus tool you use and how it's configured, you might need to enter 0, 1, 40001, or 40000 to read that same register. All four refer to the same physical data location. This isn't a bug — it's three overlapping conventions from the 1970s that refuse to die.

The Wire Protocol vs Documentation

On the wire, Modbus always uses 0-based addressing. When your master sends a request for "address 0", it gets the first register. Address 1 gets the second register. This is the absolute truth — it's what the bytes in the frame contain.

But many manufacturer manuals use 1-based numbering. They call the first register "register 1". So when you see "Register 1" in a datasheet, you need to send address 0 in your Modbus frame.

🔥 The Single Most Common Modbus Mistake

Engineer reads "voltage at register 100" in the datasheet. Types 100 into their Modbus tool. Gets voltage from register 101 (the second voltage register) or gets an exception error. The correct wire address is 99. This off-by-one error is the #1 cause of "wrong values" and exception code 02.

The 4xxxx / 3xxxx Prefix Convention

The original Modicon convention adds a prefix digit to indicate the register type:

So "40001" means "the first holding register". To get the wire address: strip the prefix digit, subtract 1. 40001 → 0001 → 0000. "40100" → 0100 → 0099.

How Different Tools Handle It

This is where it gets really fun. Different Modbus tools handle the offset differently:

Always check your tool's documentation for whether it expects 0-based or 1-based addresses.

Address Translation Cheat Sheet

Address TranslationCopy this and keep it handy
Datasheet says Tool expects Wire address ────────────── ───────────── ──────────── Register 1 0-based tool → 0 Register 1 1-based tool → 1 40001 0-based tool → 0 40001 1-based tool → 1 Register 100 0-based tool → 99 Register 100 1-based tool → 100 40100 0-based tool → 99 40100 1-based tool → 100 RULE: If in doubt, try (address - 1) first.
✨ Zero Confusion

ModBus Pro eliminates offset mistakes

Built-in device maps use the correct wire addresses — tested against real hardware. The register browser shows both the documentation address and wire address side by side, so you always know exactly what's being sent.

Download Free