Modbus Function Codes & CRC Modbus

The codes a Modbus exchange is built from, plus the checksum that wraps each serial frame. Function codes is what a request asks for — read coils, write registers, and the dec-vs-hex gotcha (FC 15 = 0x0F, FC 16 = 0x10). Exception codes is what a server sends back when it refuses, riding on the function code with its high bit set. CRC-16 builds or checks the two error-check bytes an RTU frame carries.

CodeNameWhat it does
1 0x01Read CoilsRead 1–2000 coils — the read/write discrete output bits.
2 0x02Read Discrete InputsRead 1–2000 discrete inputs — read-only bits.
3 0x03Read Holding RegistersRead 1–125 holding registers — the read/write 16-bit words.
4 0x04Read Input RegistersRead 1–125 input registers — read-only 16-bit words.
5 0x05Write Single CoilForce one coil ON (0xFF00) or OFF (0x0000).
6 0x06Write Single RegisterWrite one holding register.
7 0x07Read Exception StatusSerial only — read 8 device exception-status bits.
8 0x08DiagnosticsSerial only — line diagnostics and loopback sub-functions.
11 0x0BGet Comm Event CounterSerial only — status word and event count.
12 0x0CGet Comm Event LogSerial only — status, counts, and recent event bytes.
15 0x0FWrite Multiple CoilsWrite a contiguous block of coils in one request.
16 0x10Write Multiple RegistersWrite a contiguous block of holding registers.
17 0x11Report Server IDSerial only — device ID string and run-status byte.
22 0x16Mask Write RegisterAND/OR-mask selected bits of one holding register.
23 0x17Read/Write Multiple RegistersRead one block and write another in a single transaction.
43 0x2BEncapsulated Interface TransportRead Device Identification (MEI type 0x0E) — vendor, model.

Codes split across four data tables: coils and discrete inputs are bits; holding and input registers are 16-bit words. Which table an address lives in — and the 5-digit prefix that names it — is the subject of Modbus Decoding.

CodeNameMeaning
1 0x01Illegal FunctionThe server doesn't support that function code.
2 0x02Illegal Data AddressThe address — or the requested range — isn't valid in this device.
3 0x03Illegal Data ValueA value or quantity is out of range for that address.
4 0x04Server Device FailureAn unrecoverable error occurred while carrying out the request.
5 0x05AcknowledgeRequest accepted but long-running — poll for completion, don't resend.
6 0x06Server Device BusyBusy with a long program command; resend the request later.
8 0x08Memory Parity ErrorParity error in the extended file-record memory (FC 20/21).
10 0x0AGateway Path UnavailableA gateway is misconfigured or overloaded — no path to the target.
11 0x0BGateway Target Failed to RespondNo reply from the target device — often the wrong unit ID.

An exception response echoes the original function code with its high bit set — FC + 0x80. A failed Read Holding Registers (FC 3, 0x03) comes back as 0x83, and the byte after it is the exception code above.

Paste the frame as hex bytes — spaces, commas, and 0x are ignored. Modbus RTU uses CRC-16 (polynomial 0xA001, initial value 0xFFFF); ASCII mode uses an LRC instead, and Modbus TCP drops the checksum entirely for the MBAP header.

CRC-16 of the bytes shown
Append as (low byte first)
Full frame + CRC
Add at least 3 bytes to check an existing CRC.

The CRC is computed over every byte of the frame — unit ID, function code, and data — then appended low byte first. A receiver runs the same calculation over the whole frame including the CRC; a clean frame leaves a remainder of zero. The Append as line above gives the two bytes to add when you're building a frame; the verdict below treats the last two bytes of what you pasted as a CRC and tells you whether a captured frame checks out.

← All tools