Problem: Modbus Master Returns Exception 0x8383 on S7-1200
An S7-1200 CPU 1212C (AC/DC/RLY) equipped with a CM 1241 (CP 1241) RS-485 communication module is configured as a Modbus RTU master that polls a remote annunciation module over a 2-wire RS-485 link. After loading the TIA Portal V11.0 SP2 project, every write of process values to the slave's user registers (slave data area 1122–1169) returns the status code 0x8383 from the MB_MASTER / MB_CLIENT instruction. Read requests against the same area succeed, but no write transaction ever reaches the slave's holding register bank.
| Item | Observed value |
|---|---|
| PLC | SIMATIC S7-1200 CPU 1212C AC/DC/RLY (order code 6ES7212-1BE31-0XB0 or compatible) |
| Comm module | CM 1241 RS-485 (order code 6ES7241-1CH30-0XB0), firmware ≥ V1.0 |
| Engineering | TIA Portal V11.0 + SP2, S7-1200 CPU firmware V2.x or V3.x |
| Slave | Annunciation module, RS-485 Modbus RTU, slave ID 1, 9600/8/N/1 |
| Function | FC 16 (Preset Multiple Registers) on holding register area |
| Target register | 1122 → 1169 (48 holding registers) |
| STATUS output |
16#8383 (= 33667 decimal) |
| Behavior | Reads OK, writes always fail with 0x8383 |
STATUS word of the MB_MASTER / MB_CLIENT block. It is not a Modbus exception code returned by the slave. It is generated by the S7-1200 Modbus master instruction when the local data buffer in the MB_HOLD_REG data block is addressed outside its declared range, or when the slave rejects the request with Modbus exception 02 (Illegal Data Address).
Root Cause: MB_HOLD_REG Addressing Convention Violated
The Modbus reference model defines four separate address spaces: coils (0xxxx), discrete inputs (1xxxx), input registers (3xxxx), and holding registers (4xxxx). On a Modbus RTU slave, registers 1122–1169 are interpreted in the 4xxxx (holding register) address space. However, the Modbus RTU protocol packet itself does not contain the leading "4"; the four-digit number 1122 is sent on the wire as a 16-bit address equal to 1121 (Modbus uses zero-based register addressing inside each function code).
The S7-1200 MB_MASTER / MB_CLIENT instructions expose the MB_HOLD_REG data block as a single flat array and require a prefixed address string. The four-digit leading digit is a routing selector that tells the master which address space to use:
| Address prefix | Modbus address space | Function codes | Typical use |
|---|---|---|---|
0 or 1xxxx |
Coils (0xxxx) | FC 01, 05, 15 | Digital outputs / flags |
1 or 2xxxx |
Discrete inputs (1xxxx) | FC 02 | Digital inputs |
3xxxx |
Input registers (3xxxx) | FC 04 | Read-only 16-bit inputs |
4xxxx |
Holding registers (4xxxx) | FC 03, 06, 16, 23 | Read/write 16-bit data |
6xxxx |
Extended file / register area (vendor-specific) | FC 03, 06, 16, 23 | Large register banks > 9999 |
The original project entered the address as 1122. Because the master interprets the leading digit 1 as "discrete input / coil area" (a 1xxxx space, not 4xxxx), the request was assembled as a discrete input read against register 122 — well outside the slave's actual holding register map — and the slave rejected it with Modbus exception code 02 (Illegal Data Address). The S7-1200 then mapped that exception to its local status 0x8383.
Changing the address literal from 1122 to 41122 forces the master into the 4xxxx address space, so the request is correctly serialized as FC 16 against holding register 1122 (wire address 0x0461). The slave accepts the request, the writes complete, and 0x8383 no longer appears.
Decoding Siemens S7-1200 Modbus Master Status Codes
The STATUS output of MB_MASTER and MB_CLIENT on the S7-1200 is a 16-bit word. The MSB indicates the source (bit 15 = 1 ⇒ protocol / error class from the master; bit 15 = 0 ⇒ user/program error). Codes starting with 0x8 in the high byte are slave-originated Modbus exception codes mirrored by the master; codes starting with 0x8 in the low byte are local master-internal diagnostics. The most frequently seen codes are reproduced in the table below.
| STATUS (hex) | Meaning | Likely cause |
|---|---|---|
0x0000 |
No error | Request completed, no error |
0x80C8 |
Slave timeout | No response within configured response timeout |
0x80D1 |
Parity / framing error | Baud rate, parity, or termination mismatch on RS-485 |
0x80D2 |
CRC error | Electrical noise, wrong baud rate, daisy-chain violation |
0x80D5 |
Negative acknowledge from slave | Slave busy, retry required |
0x80E1 |
Unsupported function code | Slave does not implement requested FC |
0x80E2 |
Invalid data address | Address outside slave's valid map |
0x80E3 |
Invalid data value | Slave rejected the value (e.g., write to read-only reg) |
0x80E4 |
Slave device failure | Internal slave error |
0x80E5 |
Acknowledge, request accepted but not yet processed | Long slave processing time; increase timeout |
0x8383 |
Data address error or access outside MB_HOLD_REG address area |
Local MB_HOLD_REG DB indexing error or slave exception 02 mirrored |
0x8388 |
Mode error | Block instantiated with wrong MODE parameter |
The line between "0x80E2" (slave-side illegal data address) and "0x8383" (master-side data address out of range) is the most common source of confusion. The pragmatic diagnostic rule used on commissioning sites is:
- If
STATUSis in the0x80xxrange and the slave echoes a clean Modbus exception frame on a bus analyzer, the problem is in the slave's data map. - If
STATUSis in the0x83xxrange, the request never made it onto the bus or it was assembled with the wrong address prefix — focus on theMB_HOLD_REGDB layout, theDATA_ADDRliteral, and theDATA_LENparameter.
Modbus Function Code and Register Map for the Annunciation Slave
Annunciation / alarm-annunciator modules typically expose their user-visible registers in a fixed 4xxxx area. Although the exact register map is vendor-specific, the canonical layout for the device class shown in the source case is reproduced below; refer to the slave's own manual for the authoritative map.
| Register (4xxxx) | Width (words) | Access | Description |
|---|---|---|---|
| 1101 – 1109 | 9 | R/W | Channel enable mask (one bit per alarm channel) |
| 1110 – 1119 | 10 | R/W | Trip / setpoint thresholds |
| 1120 – 1121 | 2 | R/W | Global configuration / mode word |
| 1122 – 1169 | 48 | R/W | Per-channel acknowledge, latch, and tag data (the bank in this case) |
| 1170 – 1199 | 30 | R | Alarm history log (read-only) |
| 1200 – 1209 | 10 | R | Device identification / serial number |
Modbus RTU write transactions to the bank are typically issued with Function Code 16 (Write Multiple Registers, 0x10) because 48 contiguous registers is well below the FC 16 limit of 123 registers per PDU. The byte sequence on the wire is:
01 10 04 61 00 30 60 [96 bytes of payload] [CRC-Lo] [CRC-Hi]
where 01 is the slave address, 10 is FC 16, 04 61 is the big-endian starting register address (1122 − 1 = 1121 = 0x0461, per Modbus zero-based numbering), 00 30 is the quantity of registers (48 = 0x30), and the payload is 96 bytes (48 × 16-bit words).
Step-by-Step Fix in TIA Portal V11.0 SP2
- Open the project and navigate to the
MB_MASTERorMB_CLIENTinstance DB. - Locate the call site that issues the FC 16 write (typically a function block named
FB_Annunc_Writeor similar). Identify the input pin wired toDATA_ADDR. - Confirm that the input is a
WORD/UINTliteral that contains only the four-digit register number, not a 5- or 6-digit prefixed value. The literal1122will silently be reinterpreted as "1-prefix → coil / discrete input area → register 122" byMB_MASTER. - Change the literal to
41122(decimal) so that the prefix digit4selects the holding register space and the trailing four digits select register 1122. - Recompile and download the program block. Power-cycle the S7-1200 only if TIA Portal prompts for a cold restart (typical for V2.x firmware when the
MB_HOLD_REGDB size changes; not required if only the literal was changed). - Force a single write cycle and observe the
STATUSoutput ofMB_MASTER. The expected value is now16#0000for a successful transaction. - Read back the same register bank (FC 03, DATA_ADDR = 41122, DATA_LEN = 48) and confirm the written values match the source DB.
MB_CLIENT uses a different address string format. S7-1500 MB_CLIENT requires the data type UINT in 1-based notation and a separate MB_MODE parameter. The "41122" convention is specific to S7-1200 MB_MASTER. When migrating, recalculate the address scheme.
Hardware and Cabling Checks (RS-485)
Even after the addressing issue is resolved, persistent 0x8383 / 0x80E2 faults sometimes reappear when the physical layer is marginal. Confirm the following before declaring the issue closed:
| Item | Acceptance criterion |
|---|---|
| Baud rate / parity | Identical on PLC port and slave (default 9600/8/N/1 for most annunciators) |
| Cable | Twisted pair, shield grounded at one end only, characteristic impedance ≈ 120 Ω |
| Termination | 120 Ω at each end of the trunk; never on stub branches |
| Stub length | < 3 m at 9600 baud; stricter for higher baud rates |
| Bias | Many slaves do not provide fail-safe bias; add 680 Ω pull-up to +5 V on D1 and 680 Ω pull-down to GND on D0 if the bus floats when the master is offline |
| Shield | Bonded to panel ground at one end; do not let shield carry return current |
| Common mode | Slave and PLC share the same 0 V reference (or use an isolated repeater if not) |
The CM 1241 RS-485 module ships with an internal 390 Ω pull-up on D1 (B) and 390 Ω pull-down on D0 (A) that acts as a weak fail-safe bias. If the bus is otherwise unterminated, you can leave the internal bias enabled; disable it if you install a third-party repeater or terminator that already provides bias, to avoid loading the line.
Verification Procedure
- Place the S7-1200 in RUN with the corrected program. Open a watch table on the
MB_MASTERinstance DB and monitorDONE,ERROR, andSTATUS. - Trigger a single write. Confirm
DONE = 1andSTATUS = 16#0000within one scan of the master'sREQfalling edge. - Issue a read against the same register bank and compare the returned values to the written values in the source DB. A byte-level match confirms end-to-end integrity.
- Cycle power to the slave and re-issue the write. The slave should accept the broadcast without re-initialization (Modbus RTU is stateless on the master side; the slave may need to refresh its NVRAM-mirrored parameters).
- Capture a Modbus RTU trace on a third-party analyzer (e.g., a laptop running Modbus Poll in sniffer mode) and verify that the on-wire PDU matches the expected FC 16 frame shown above.
Alternate Addressing Forms and Edge Cases
Siemens has used three addressing schemes for the S7-1200 Modbus master over the product's lifetime. Knowing which scheme your firmware uses prevents the 0x8383 trap from re-appearing in a future firmware upgrade.
| CPU firmware | DATA_ADDR form for HR 1122 | Library block |
|---|---|---|
| V1.x – V3.x (classic MB_MASTER) | 41122 (decimal) | Modbus_Comm_Load + MB_MASTER from "Modbus" library |
| V4.x – V4.6 (extended MB_MASTER) | 41122 (decimal), full 6-digit form accepted | Same blocks, extended DATA_LEN up to 200 words |
| V5.x with MB_CLIENT (PtP) | 41122 — same convention; MODE selects FC | MB_CLIENT only, MODE = 16 for write |
Note that some annunciator manufacturers publish register maps that number from 40001 (1-based with the 4 already factored in) rather than from 1. The conversion rule is: modbus register number = slave map address − 40000 (e.g., map address 41122 ⇒ register 1122 ⇒ use DATA_ADDR = 41122 in the S7-1200 because the leading 4 selects the HR space and the remaining 1122 is the offset within that space). A discrepancy here is the second most common cause of 0x8383 in the field.
Troubleshooting Matrix
| Symptom | First-line diagnosis | Remedy |
|---|---|---|
| STATUS = 0x8383, no traffic on bus | DATA_ADDR literal missing leading 4 or using wrong data type | Use 4xxxx notation (e.g. 41122), confirm literal is WORD/UINT
|
| STATUS = 0x8383, slave echoes exception 02 | Slave map is numbered from 1 instead of 0, or vice versa | Add or subtract 1 from the suffix; verify against the slave's own register map |
| STATUS = 0x80E1 | Slave does not support FC 16 | Switch to FC 06 (single register) or fall back to multiple FC 06 transactions |
| STATUS = 0x80C8, no reply | Response timeout too short, or slave not addressed | Increase RESP_TIMEOUT on Modbus_Comm_Load; verify slave ID matches |
| STATUS = 0x80D1 / 0x80D2 | Baud rate / parity / termination | Verify CM 1241 port configuration matches slave; install / remove termination |
| STATUS = 0x80E3 | Slave rejected the value (e.g., write to a read-only or out-of-range register) | Check slave's per-register R/W permission; some annunciators only accept writes when in CONFIG mode |
| STATUS = 0x0000 but slave values do not change | Slave acknowledged but did not persist (e.g., requires CONFIG-mode commit) | Issue the vendor's "save parameters" command after the bulk write |
Documentation References
For the commissioning engineer, the authoritative references for this case are the Siemens S7-1200 Modbus/USS programming manual and the CM 1241 RS-485 module manual, plus the Modbus Organization's specification for protocol-level behavior. Use these documents to validate any register map or error code interpretation before applying it in production.
- Siemens Industry Online Support — S7-1200 product pages and KB articles
- Modbus Organization — Modbus Application Protocol V1.1b3 specification
- Modbus Organization — Introduction to Modbus
- ABB Modbus RTU Communication Module (>125A) product page (representative of Modbus-RTU annunciation-class peripherals)
FAQ
What does Modbus error 0x8383 mean on an S7-1200 with CM 1241?
0x8383 (decimal 33667) is the Siemens-specific status code "Data address error or access outside the MB_HOLD_REG address area." It is reported by MB_MASTER / MB_CLIENT when the request is built with an address outside the local MB_HOLD_REG DB range, or when the slave returns Modbus exception 02 (Illegal Data Address) and the master mirrors that condition locally.
Why does entering 1122 fail while 41122 succeeds?
The S7-1200 Modbus master requires a prefix digit on DATA_ADDR to select the Modbus address space. 1122 is interpreted as the 1xxxx (coil/discrete input) space at offset 122, which the slave rejects. 41122 selects the 4xxxx (holding register) space at offset 1122, which is where the annunciator's user register bank actually lives.
Which function code should I use to write 48 contiguous holding registers?
Use FC 16 (Write Multiple Registers, 0x10). Set MODE = 16 on the Modbus master, DATA_ADDR = 41122, and DATA_LEN = 48. Verify that the slave implements FC 16 — some low-end annunciators only support FC 06 (Write Single Register), in which case issue 48 sequential FC 06 requests.
Do I need to power-cycle the S7-1200 after changing only the DATA_ADDR literal?
No. A change to a constant input on the master block can be downloaded in RUN (where supported) or after a STOP→RUN transition. A power cycle is only required when the size of the MB_HOLD_REG data block changes, because the CPU re-allocates the data block on cold start.
What is the maximum number of registers I can write in a single FC 16 transaction on the S7-1200?
The S7-1200 MB_MASTER supports up to 200 words per request on firmware V4.x; on earlier firmware (V2.x/V3.x, the version used in the source case) the limit is 125 words. Modbus RTU itself caps FC 16 at 123 registers per PDU, so the effective limit is 123 words.