I have lost most of an afternoon to a power meter that read perfectly in the vendor's own laptop tool and came back as nonsense in the PLC. Same cable, same switch, same IP address. The answer was that the meter's documentation and the controller's documentation were counting registers from different starting points, and neither one was wrong.
That is one of the two things that actually burn time on Modbus TCP. The other is a link that comes up, runs fine for a while, then stops, with nothing going red anywhere. Both are documented behavior. Neither is obvious from the outside. So here is what the specifications actually say about the two of them, plus the spot where one vendor manual argues with itself.
The 40001 problem, and what the standard actually says
Start with the part the standard is clear about. In a Modbus TCP request, the register address on the wire runs from 0 to 65535. The MODBUS Application Protocol Specification V1.1b3 states it plainly under function code 03: registers are addressed starting at zero, so registers numbered 1 to 16 are addressed as 0 to 15.
So the data model counts from 1 while the wire counts from 0. That off-by-one is deliberate, it is in the standard, and it is the smaller half of the problem.
Here is the bigger half. The 4xxxx numbering everyone uses, 40001 for the first holding register and 30001 for the first input register, appears nowhere in the Modbus specification. Not in the Application Protocol Specification V1.1b3, not in the MODBUS Messaging on TCP/IP Implementation Guide V1.0b. Zero mentions in either document. It came out of the original Modicon controllers, it stuck because it was useful, and because it is a convention rather than a spec, every vendor is free to implement it their own way.
The standard says so out loud, incidentally. Under its addressing model it states that the pre-mapping between the Modbus data model and the device application is totally vendor device specific. That is not an oversight. It is a deliberate hole, and the 4xxxx convention grew into it.
So a register number printed in a device manual carries two questions the number itself cannot answer:
Β·Β Β Β Β Β Β Does that number already include the 40000 offset, or not? "Register 40023" and "register 23" are frequently the same register described by two different authors. One of them expects you to subtract.
Β·Β Β Β Β Β Β Is it 1-based or 0-based? Whoever wrote the manual either counted from the data model or counted from the wire, and both are legitimate.
The leading digit is supposed to tell you which table you are in, and by extension which function code to send: 4 for holding registers with function code 03, 3 for input registers with function code 04. That part of the convention is mostly respected. It is also why a 3xxxx number requested with function code 03 comes back as an exception or, worse, as clean data from the wrong table.
Miss the offset question and you land 40000 registers away, which is obvious inside a minute. Miss only the base question, 1-based versus 0-based, and you land a single register away. That is the expensive version, because a plausible number shows up on the screen and you go off looking for a scaling problem.

Same printed register number, three legitimate requests on the wire. Only the vendor's own documentation resolves it.
One vendor's formula, and the line where its own manual disagrees with itself
Rockwell's 20-COMM-M is a Modbus TCP adapter that bolts onto a PowerFlex drive, and its user manual, publication 20COMM-UM014C-EN-P, is a good demonstration of how far a real device can sit from anything resembling "register 40001."
On that adapter every drive parameter, whether it holds 16 bits or 32, occupies two consecutive registers, a Lo Word and a Hi Word. The starting register comes out of a formula:
Starting Register Address = (Device Parameter No. x 2) - 1
Say you want parameter 003, Output Current, off a PowerFlex 70. Three times two is six, minus one is five. Read register 5 for the Lo Word and register 6 for the Hi Word, together, as a pair. That is the worked example in the manual and it is correct.
Then comes the tip for 0-based masters, and this is where it comes apart. The manual tells you to subtract 1 from the starting register address, which gives 4, and then to read "register address 4 (Lo Word) and register address 6 (Hi Word)."
Four and six. Those are not contiguous. The same section of the same manual states that a parameter always occupies two contiguous register addresses, and that the starting address and the next contiguous address have to be read together as a pair. Subtract one from both halves and you get 4 and 5. The 6 was carried down from the 1-based example sitting directly above it and never adjusted.
It is a typo in a document that has been through multiple revisions, and it is an expensive one, because 4 and 6 does not fail. On a 0-based master, address 4 holds the low word of parameter 003. Address 6 belongs to parameter 004. Follow the tip literally and you assemble a 32-bit value out of two unrelated parameters. It has a magnitude, it moves when the drive runs, and it means nothing at all.

Parameter 003 on a 20-COMM-M. The bottom row is what the manual's 0-based tip actually tells you to read.
The Unit Identifier on this adapter is the other thing that catches people. On a plain Modbus TCP server that field is close to vestigial, since the IP address already picks out the device. The 20-COMM-M reuses it as the DPI port number, 0 through 6, so it selects which piece of hardware in the drive stack you are addressing. Port 0 is the drive itself, port 5 is a peripheral on the drive's internal port, and a Unit Identifier of 255 always lands on the adapter's own parameters no matter which port it is plugged into. Aim it at the wrong number and you get a perfectly valid response describing the wrong device.
When a manual leaves the numbering genuinely ambiguous, I stop reading it and go find out empirically. Pick a block you are certain is safe to write. Load it with values you will recognize on sight, 11 then 22 then 33 then 44, and read it back from the other side. Wherever the 11 turns up is your real starting offset, and the argument is over. Two minutes, and it beats a second pass through the documentation. Just be honest with yourself about the "safe to write" part first, because a holding register on a running drive is not a scratchpad.
Why the connection drops when there is nothing wrong with the wire
The second half has a documented mechanism behind it that almost nobody thinks to go looking for.
The Implementation Guide recommends keeping the TCP connection open with a remote device rather than opening and closing it for every transaction. Most competent clients already do that. But the same document also specifies what a server should do when it runs out of connection slots, and that is the sentence worth having: close the oldest unused connection.
Read that again with a real plant in your head. A drive or a meter has some fixed number of slots. You have SCADA polling it, an HMI subscribed to it, a controller talking to it, and then somebody walks up and plugs a laptop in with a configuration tool. The device is now over its limit, so it drops the oldest connection that has not been busy. Which is very often the HMI screen nobody is standing at, or the historian that polls once a minute. Nothing failed. Nothing went red. The device did exactly what it was told to do, and your slowest poller is gone until it notices and reconnects.

The device is not broken. It is following the Implementation Guide's recommendation to close the oldest unused connection.
There is more in the guide on this. It describes two pools of connections. One is a priority pool, tied to specific configured IP addresses, and connections in it are never closed on the device's own initiative. Everything else lands in a non-priority pool, and that is where the oldest connection gets dropped once a new request arrives with nothing free. Where a device actually implements that, your critical clients belong in the first pool. The guide also recommends capping how many connections any single remote device may hold, so one chatty client cannot swallow the whole priority pool by itself.
Then there are the numbers, and the headline figure on a datasheet is almost never the figure to plan against.
|
Device |
What the specification says |
What you actually get for plain polling |
|
Any Modbus TCP server, per the Implementation Guide |
A NumberMaxOfServerTransaction value from 1 to 16 |
Whatever the vendor chose. The guide requires it to be published as a device feature |
|
Rockwell 20-COMM-M |
30 TCP connections |
1 Modbus TCP I/O connection. The other 16 are CIP messaging |
|
ProSoft MVI69E-MBTCP |
20 client and 20 server connections |
10 MBAP connections. The other 10 server slots are encapsulated Modbus |
Β
Both of those product numbers are honest. Neither is the number you build a polling architecture on. Thirty TCP connections on a 20-COMM-M is real, and the count of Modbus TCP I/O connections it will hand you is one. Twenty server connections on an MVI69E-MBTCP is real, and half of them are for encapsulated Modbus rather than the standard MBAP framing most masters speak.
There is a genuine disagreement between the two official documents on the exception code for this, and it sends people the wrong way. The Application Protocol Specification lists code 06 as Server Device Busy and describes it as specialized use with programming commands, a server occupied with a long-duration program command. Go hunting for a program command and you will find nothing, because nobody is programming anything. The TCP Implementation Guide describes the same code quite differently: the server was unable to accept the request, and it returns code 06 specifically when it has no free transaction slots left. On Modbus TCP the second reading is the useful one. Exception 06 normally means you are asking for more concurrent transactions than the device can hold.
On timeouts the guide is blunt to the point of being unhelpful, and it is worth knowing that it is deliberate: there is no specified response time for a Modbus TCP transaction. None at all. The stated reasoning is that the same protocol has to serve I/O scanners expecting sub-millisecond timing and long distance radio links with delays of several seconds. What the guide does tell you is that the client timeout must be longer than the worst reasonable response time. Set it shorter and the retries themselves congest the device and the network, which generates more errors. Anyone who has tightened a timeout to fix a flaky poll and made it measurably worse has met that mechanism from the wrong end.
Device-side timers are a separate thing and they are the ones that surprise people. The 20-COMM-M carries a communication loss timer in parameter 19, defaulting to five seconds, settable up to 180 or disabled outright. It also has a Keep-Alive register at address 10002: write any non-zero value into it and that timer resets. The manual's own example is that with the timer at its five second default you write to 10002 every 4.9 seconds or less. Note what this is not. It is not TCP keepalive. The socket underneath can be in perfect health while the application timer expires on top of it and faults the drive.
A few smaller items from the same documents, worth having before you start suspecting hardware:
Β·Β Β Β Β Β Β Port 502 is mandatory. Devices may offer a configurable Modbus TCP port, and the 20-COMM-M has a parameter for exactly that, but the guide is explicit that 502 has to remain available in addition to any application-specific port.
Β·Β Β Β Β Β Β The client's local port must be above 1024 and different for every client connection. Worth knowing before writing a firewall rule that only permits 502 in both directions.
Β·Β Β Β Β Β Β One TCP frame carries one ADU. The guide advises against putting multiple Modbus requests or responses into the same TCP payload, which is a thing homegrown masters do to save round trips and then cannot explain.
Β·Β Β Β Β Β Β Duplicate IP address detection exists on these adapters and presents as the network indicator going steady red on a 20-COMM-M. Two devices sharing an address is quick to rule out and ugly to chase from the software side.
The security question, answered straight
Plain Modbus TCP has no authentication and no encryption. Anything that can reach port 502 can write to a coil.
There is an official answer. Modbus.org registered a security variant, Modbus/TCP Security, on system port 802, which wraps the same unchanged ADU inside TLS 1.2 or newer with mutual client and server certificate authentication and authorization roles carried in x.509v3 certificate extensions. I have yet to walk into a plant where it was actually deployed, and I would not plan a project around finding it on equipment you already own.
Long before that variant existed, the Implementation Guide already described something more useful day to day. It calls it an access control module: the server checks the IP address on an incoming connection request and refuses the ones that are not authorized. That, plus keeping Modbus TCP traffic on a segment of its own away from anything with a web browser on it, is the version of this that gets built in practice.
FAQ
What port does Modbus TCP use?
Port 502, and it is mandatory. The Implementation Guide allows a device to offer an additional configurable port for markets that need one, but it states directly that port 502 must still be available alongside it. On the client side the local port is a different matter: it has to be above 1024 and unique per connection.
Why does my Modbus TCP connection keep dropping?
Before suspecting the cable, count your clients against the device's connection slots. A server that is out of slots is documented to drop its oldest idle connection, so the poller that fell over is often the slowest or least busy one rather than the one with an actual problem. Also check the device's own communication loss timer, which runs independently of TCP and will fault on schedule while the socket underneath is still healthy.
Is register 40001 the same as register 1 in Modbus TCP?
Usually, but the number alone cannot tell you. The 4xxxx numbering does not appear in the Modbus specification at all, and the specification explicitly leaves that mapping up to the vendor. So the manual has to tell you two things: whether the printed number already includes the 40000 offset, and whether it counts from 0 or from 1. When the manual will not say, write a recognizable pattern into a block that is safe to write, then read it back and find the real offset yourself.
How many devices can I poll over Modbus TCP?
The serial-line node limit does not apply here, because IP addresses do the addressing. Your real ceilings are the master's own connection capacity and each server's slot count, and that second one is per catalog number rather than per protocol. It belongs on the checklist before the network design, not after.
What to check before you order
IQElectro carries Modbus TCP interface hardware, including the ProSoft MVI69E-MBTCP for 1769 CompactLogix racks and the PLX31 and PLX32 series gateways, mostly surplus and open-box. If you are replacing an adapter rather than designing a network from nothing, the specification worth checking before you order is the connection budget on that exact catalog number. As the table above shows, two modules that both say Modbus TCP on the front can hand you very different numbers of usable connections.