Skip to content
Start free evaluation

Service errors and timeouts

A service error means the command itself failed. Unlike a Modbus exception response, there’s no result. The same error looks like this in each environment:

Environment Appearance
C PDCOMM_MODBUS_SERVICE_ERROR (5) with the error buffer {"error":"<message>","ok":false}
C++, Qt, MFC std::runtime_error whose what() is the whole error JSON
.NET ModbusCommandException (derives from InvalidOperationException); Message is the message only, and Code is the code of license errors
Headless An {"error":"<message>","ok":false} line and exit code 1
MCP isError true, with the message in content[0].text
GUI <command> failed: <message> in the status line

The messages below are verbatim. The OS error text inside Io(...) differs between operating systems.

Message Cause and fix
Action is required The action member is missing.
Unknown service action The action name is wrong. Check the JSON command reference.
key must be a string at line 1 column 2, EOF while parsing an object at line 2 column 0 and similar A JSON syntax error. The headless simulator and MCP take one object per line.
Input exceeds one MiB A headless or MCP line is longer than 1 MiB.
missing field `port` , unknown field `extra`, expected one of ... A configuration or model member is missing or unknown.
PDU is required request or execute has no pdu.
Invalid hex length, Invalid hex The hex string has an odd number of digits or a non-hex character.
Expected a byte array or hex string pdu or bytes is neither a string nor an array of 0–255.
Invalid unit unit is outside 0–255.
Message Cause and fix
Invalid endpoint configuration One of: a wrong transport, role or parity value; unit outside 1–247; timeout_ms or ascii_timeout_ms of 0 or above 60000; turnaround_ms above 60000; baud of 0; stop_bits other than 1 or 2; parity none with stop_bits 1
Gateway requires a serial bus transport Set a gateway’s transport to rtu or ascii.
Invalid gateway route A routes key is 0, or a value is 0 or above 247.
Invalid Security configuration security is used with a serial transport, mode is wrong, or chain, private_key or trust is empty.
invalid type: string "Invalid JSON", expected struct Security The JSON in the GUI’s Security tab doesn’t parse.
Protocol is excluded from this build The SDK doesn’t include the configured transport or Security; check capabilities.
Disconnect before changing configuration You can’t change the configuration while connected. disconnect first.
Endpoint is already connected Already connected. disconnect before connecting again.
Message Cause and fix
Invalid TCP address address isn’t in IP:port form. Host names such as localhost:1502 aren’t accepted; write 127.0.0.1:1502.
Io(ConnectionRefused, "Connection refused (os error 61)") No server listens at that address. Check that the server connected first and uses the same port.
Io(TimedOut, "connection timed out") The TCP connection wasn’t established within timeout_ms. Check the route, firewalls and the device’s power.
Io(AddrInUse, "Address already in use (os error 48)") Another program holds the server port. Use another port or stop that program.
Io(AddrNotAvailable, "Can't assign requested address (os error 49)") The server address IP isn’t an address of this computer. Use 0.0.0.0 or the computer’s real address.
InvalidConfig The serial port is empty.
Io(Other, "No such file or directory") The serial port path doesn’t exist.
Io(Other, "Unable to acquire exclusive lock on serial port") Another program has the serial port open.
Security(...), Config(...), Crypto(...) Modbus/TCP Security errors; see Security connection problems.

The SDK libraries (C, C++, .NET, Qt, MFC) check the license on connect. The headless and MCP simulators don’t check it, and the simulator GUI uses its embedded tool license. License error replies carry a code in addition to error, so your program can tell them apart.

code Message Cause and fix
license_required PDComm license required for module 'modbus' (<state>): … There’s no license for connect. It needs the modbus module, plus modbus-security when the configuration has security. Nothing was opened. license in the reply holds module, state, and license_id; look up state in license troubleshooting. Endpoints that are already connected keep working.
license_invalid License text is required, license text contains no PDCOMM LICENSE block, license text contains no valid license (<reason>), or license text is larger than 1048576 bytes license_install has no text, the text has no license block with a valid signature, or it’s larger than 1 MiB. The license installed earlier stays. Pass the whole file you received, unchanged.
host_id_unavailable Host id unavailable: <reason> host_id couldn’t read the machine id. In a container, create /etc/machine-id. See Host ids.

A refused connect replies like this:

{"code":"license_required","error":"PDComm license required for module 'modbus' (missing): no valid license for this module was found. Existing connections keep running. Install a license with the license API, PDCOMM_LICENSE_FILE or a pdcomm.license file.","license":{"license_id":null,"module":"modbus","state":"missing"},"ok":false}
Message Cause and fix
Connect a client before sending a request Not connected as a client. Sending request in the server role also gives this.
Timeout No response within timeout_ms. See Timeouts below.
Closed The TCP connection is already closed: after a timeout, after the peer closed it, or after an I/O error. state reports connected as false. connect again.
Io(ConnectionReset, "Connection reset by peer (os error 54)") The peer reset the connection. A plain client talking to a Security server also gets this.
Unsupported A TCP client tried to send a serial-line-only function (07, 08, 11, 12, 17).
InvalidConfig A serial client sent something other than a write to unit 0, or a unit above 247.
Protocol(Correlation) The response doesn’t match the request (another unit, function code or transaction identifier). Check for several devices answering at one address, and the gateway settings.
Protocol(Length), Protocol(Value) The response’s length or values don’t fit the function. An exception response isn’t an error even when its code is undefined (such as 07); it’s a result with "status":"exception".
Protocol(Checksum), Protocol(Encoding), Protocol(Address) A serial response has a wrong CRC or LRC, an invalid ASCII character or a wrong address. See Serial communication problems.

A PDComm client checks a request PDU before sending it and doesn’t send an invalid one. The message is then a single word:

Message Examples
Length The length doesn’t fit the function: 0700, an empty PDU
Value A quantity of 0 or above the limit, a wrong function 05 value: 0300000000
Address Address plus quantity beyond 65536, a wrong file reference: 03FFFF0002
Function An unsupported function or diagnostics sub-function: 0800130000

Running the same PDU with execute shows the server-side behavior instead: an exception response (01, 02 or 03).

Timeout means the request was sent but no response arrived within timeout_ms. If it was a write, the device may already have applied it, so read the value before writing again.

What to check on TCP

  1. Make sure the peer is a Modbus server that answers. The port may be open but belong to another protocol’s service.
  2. Check the unit identifier. Some devices and gateways ignore unknown units.
  3. If the peer is a gateway, make timeout_ms longer than the gateway’s serial wait.
  4. If the peer is a server built with the SDK, check that the application keeps calling poll. A server that stops polling still accepts connections but never answers.
  5. In the failed record of the diagnostic log, look at tx_bytes (bytes sent), rx_partial_bytes (bytes of a partial response) and max_poll_gap_us (SDK processing delay).

After a timeout, a TCP client closes the connection so that a late response can’t be paired with the next request. Later requests fail with Closed, so connect again.

For timeouts on a serial line, see Serial communication problems.

A wrong address returns the value of another register without any error, or exception 02.

Symptom Common cause
You get the value of the neighboring register You didn’t subtract 1 from a one-based manual number (40001), or subtracted 1 from an address that was already zero-based.
Exception 02 You kept the table prefix digit: 40001 is address 0, not 40000.
The value is always 0 or unrelated Wrong table: measurements are often input registers (04) and settings holding registers (03).
A 32-bit value is far off The two registers are in the opposite order from the device (ABCD vs CDAB).
A negative number shows as 65000-something You read a signed 16-bit value as unsigned.

To confirm:

  • Find a register with a fixed value in the manual, such as a device ID or firmware version, and read it first. The expected value proves your address base.
  • Read the addresses around it to find where the expected value lives.
  • Data model and addresses explains the conversion.
Message Cause and fix
Table is required, Address is required, Values are required A data_set member is missing.
Unknown data table table must be coils, discrete_inputs, holding_registers or input_registers.
Invalid data values values is empty, a bit table got a value other than 0 or 1, or the address is above 65535.
Address outside configured table The address is outside the model’s table. Check start and size with data_get.
Model is required model_set has no model.
Bit table values must be zero or one Coils or discrete inputs contain a value other than 0 or 1.
Invalid table range A table’s start address plus count leaves the 16-bit address range.
Invalid file, FIFO or device identification model One of: file number 0 or more than 10000 records, more than 31 FIFO values, a missing object 0, 1 or 2, a reserved object 7–127, an object over 244 bytes, or a server_id outside 2–251 bytes.
Invalid diagnostic register The register of diagnostics_set is above 65535.
Project is required project_import has no project.
Disconnect before loading a project Disconnect, then load.
Unsupported Modbus project kind or version kind must be pdcomm.modbus.project and version 1. If you saved the whole {"ok":true,...} reply, save only result.
Fault bytes are required, Fault input exceeds limit fault has no bytes, or more than 4096.
Transport is excluded The transport of fault isn’t in the build.
Serial transports are excluded serial_ports in a build without serial transports.
Message Cause and fix
Logging configuration is required logging_configure has no config.
Invalid logging level level must be error, warn, info, debug or trace.
Unknown logging option The configuration has an unknown member.
Logging limits are out of range max_bytes (8192 bytes to 1 GiB) or files (1–16) is out of range.
Forensics requires debug or trace logging Enable forensics only at the debug or trace level.
Cannot open logging sink The log file can’t be opened. Check that the folder exists and is writable.
Logging flush failed Records weren’t written within two seconds, or writing failed. Check write_errors in logging_status.
Message Cause and fix
Usage: pdcomm-modbus-headless [--scenario path] Wrong arguments (exit code 2).
Scenario step N field <member> did not match A scenario expectation differs from the result (exit code 1).
Expected fields must be an object expect isn’t an object.
Scenario exceeds one MiB The scenario file is larger than 1 MiB.
Endpoint poll failed: <error> A server’s or gateway’s poll failed and it disconnected. Read the error, then connect again.