Skip to content

Server: answer ILLEGAL_VALUE for out-of-range read counts - #3066

Merged
janiversen merged 7 commits into
pymodbus-dev:devfrom
akbarsiddic:fix/server-read-count-illegal-value
Oct 19, 2026
Merged

janiversen merged 7 commits into
pymodbus-dev:devfrom
akbarsiddic:fix/server-read-count-illegal-value

Conversation

@akbarsiddic

Copy link
Copy Markdown
Contributor

Problem

When a client sends a read request (FC1/FC2/FC3/FC4) whose quantity exceeds the MODBUS maximum (2000 bits, 125 registers), the pymodbus server answers 0x01 ILLEGAL FUNCTION instead of the specification-required 0x03 ILLEGAL DATA VALUE.

Reproduced on the wire (FC3, count=126): the response is ... 01 83 01; the expected response is ... 01 83 03.

Root cause

verifyCount(MAX_COUNT) was added to x_decode() by #2997. It raises ValueError, which DecodePDU.decode() catches and converts into ModbusIOException; ServerRequestHandler then answers ILLEGAL_FUNCTION. The count never reaches datastore_update(), the layer that can return ILLEGAL_VALUE.

Fix

Finish the pattern established for FC23 writes by #3016 (see test_readwrite_decode_write_count_above_limit): x_decode() parses; datastore_update() validates and returns ExceptionResponse(fc, ExcCodes.ILLEGAL_VALUE).

  • Removed the decode-time verifyCount() from FC1, FC2, FC3, FC4 and from the FC23 read_count.
  • Added if not 1 <= count <= MAX_COUNT: return ExceptionResponse(self.function_code, ExcCodes.ILLEGAL_VALUE) at the top of each read datastore_update, before any datastore access.
  • x_encode() keeps its verifyCount() — API misuse still raises.
  • FC23 write_count behaviour and all MAX_COUNT constants are unchanged.

Tests

  • PDU: out-of-range and zero counts answer fc | 0x80 with exception 0x03, and the datastore is not queried (assert_not_awaited); a count exactly at MAX_COUNT is accepted; decode accepts over-max frames.
  • Integration: a TCP round-trip asserts the wire response bytes ... 01 83 03; reverting the fix reproduces ... 01 83 01.

Out of scope

FC15 (WriteMultipleCoilsRequest) has the same class of decode-time count bug and will be addressed in a follow-up.

@janiversen janiversen left a comment

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

LGTM, thanks

@janiversen
janiversen merged commit 5951cb5 into pymodbus-dev:dev Oct 19, 2026
16 checks passed
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants