Automation Glossary • DNP3 Function Code

What Is a DNP3 Function Code?

Merobix Engineering • • 7 min read

When you decode a DNP3 exchange, one byte in each application fragment tells you what the message is asking for: the function code. Reading a capture, writing a point map, or diagnosing a rejected command all get easier once you can name the common function codes at sight. This page lists the request and response function codes you meet most, groups them by purpose, and shows how they drive a typical master-outstation conversation.

Back to Blog

DNP3 Function Code in one line: A DNP3 function code is a single byte in the application layer that names the action of a message. Requests use codes such as read (1), write (2), select (3), operate (4), direct operate (5), cold restart (13), warm restart (14), and enable/disable unsolicited (20/21). Outstations reply with response (129) or unsolicited response (130). The function code is the verb of the exchange, telling the receiver what to do or what kind of answer it is returning.

Request Function Codes a Master Sends

Master requests fall into a few families. Data requests are dominated by read (function code 1), which a master uses to poll classes and static data. Configuration and control use write (2) for values like the clock, and the control set - select (3), operate (4), and direct operate (5) - to command outputs. The select-then-operate pair underpins the select-before-operate handshake, while direct operate does it in one pass.

Device management has its own codes: cold restart (13) and warm restart (14) reboot an outstation, which is the mechanism behind a DNP3 cold restart. Enable unsolicited (20) and disable unsolicited (21) turn spontaneous reporting on and off, and immediate freeze codes capture counter snapshots. Knowing which family a code belongs to tells you at a glance whether a frame is reading, commanding, or managing the device.

Response Function Codes an Outstation Returns

Outstations have far fewer function codes because they mostly answer. The main one is response (129), returned to any solicited request - a poll, a write acknowledgement, a control confirmation. It always carries the two-byte internal indication field so status rides along with the data.

The second is unsolicited response (130), which an outstation sends on its own initiative when configured for it, without waiting to be polled. Distinguishing 129 from 130 in a capture immediately tells you whether the outstation was answering the master or reporting spontaneously, which is central to understanding the DNP3 unsolicited response model. A confirm (function code 0) can flow in either direction to acknowledge receipt at the application layer.

The Verb Needs a Noun: Function Codes and Object Headers

A function code almost never travels alone. Most requests pair the code with one or more object headers that name what the verb acts on: an object group, a variation, and a qualifier with a range or count. Read (1) plus a class object asks for buffered events; read plus a static object group asks for present values; write (2) plus a group 50 time object sets the clock. The function code says what to do, the object header says what to do it to, and the qualifier's range selects which point indexes the request touches. Decoding in that order - verb, then noun, then range - turns a wall of hex into a sentence you can read aloud.

This pairing explains why two frames with the same function code can be doing completely different jobs. A read of class 1, 2, and 3 objects is an event poll; a read of the same outstation's counters is a totalizer collection; both carry function code 1. Responses work the same way: response (129) is just the envelope, and the object headers inside tell you whether it carries binary input events, analog values, or nothing but status. When you compare a capture against a device's documentation, check both dimensions, because a device can support a function code but not the object group you asked for, and from the master's side the failure looks identical either way.

A Poll Cycle Read at the Function-Code Level

The table below lists the codes you will meet in a routine exchange, using symbolic traffic rather than any particular implementation's defaults. Committing these to memory covers the overwhelming majority of frames in a normal capture.

CodeNameSent by
0ConfirmEither end
1ReadMaster
2WriteMaster
3 / 4 / 5Select / Operate / Direct operateMaster
129ResponseOutstation
130Unsolicited responseOutstation

Now read a cycle with those codes in hand. The master sends read (1) for the event classes; the outstation answers with response (129) carrying its buffered events and requests a confirmation; the master returns confirm (0), and only then does the outstation clear those events from its buffer. Later a field point changes and the outstation, with unsolicited reporting enabled, sends unsolicited response (130) on its own initiative; again the master confirms. Periodically the master issues an integrity poll - still function code 1, but requesting class 0 static data along with the event classes - to guarantee its database matches the field even if a message was lost along the way. Every step of that story is legible from the function-code byte alone.

Diagnosing Rejected and Unsupported Requests

DNP3 has no dedicated error function code for requests the outstation cannot honor. Instead, the outstation replies with an ordinary response (129) and raises bits in the internal indication field: one bit for a function code it does not implement, another for an object group it does not know, another for a parameter it cannot accept. A master that ignores those bits will happily log the exchange as successful while the command quietly did nothing. So the first move when a write or control seems to vanish is to read the IIN bits in the response, not to resend the request harder.

When a request is rejected, work from documentation toward the wire. Check the outstation's device profile to confirm the function code and object group are supported at all, then confirm the implementation subset level the device claims, because DNP3 defines subset levels and a code that is optional at the device's level may simply be absent. If the paperwork says it should work, capture the exchange and compare the exact function code, group, variation, and qualifier against a known-good request to the same device. In practice the gap is almost always in the noun rather than the verb: right function code, wrong object header.

Frequently Asked Questions

What is the DNP3 read function code?

Read is function code 1. A master sends it to request data - a class poll, a static-data read, or a read of a specific object group and range. It is the most common request byte you will see in a DNP3 capture.

What is the difference between direct operate and operate?

Direct operate (5) commands an output in a single request. Operate (4) is the second step of the select-before-operate sequence, sent only after a matching select (3) has been echoed back by the outstation, adding a confirmation step before the output moves.

How do I tell a response from an unsolicited response?

Response is function code 129 and answers a master's request. Unsolicited response is 130 and is sent spontaneously by the outstation. The code alone tells you whether the outstation was polled or reported on its own.

Is the application-layer confirm the same as a link-layer acknowledgment?

No. Confirm (function code 0) is an application-layer message that tells the sender its fragment was processed, and it is what allows an outstation to clear reported events from its buffer. The data link layer has its own acknowledgment mechanism below it. A link can acknowledge a frame that the application layer later fails to act on, which is why event handling keys off the application confirm rather than the link-layer handshake.

Which function codes should a hardened installation restrict?

Reads and confirms are the low-risk core of polling. The codes that change state deserve control: the select, operate, and direct operate family, writes, cold and warm restarts, and the enable and disable unsolicited pair. Many secure designs permit only the codes each master genuinely needs and alarm on anything else, following the site's security policy and the judgment of qualified security personnel.

Sources and verification

This page references the protocol specifications published by the organizations below. Editions, product capabilities, and documentation change over time - confirm current requirements and specifications directly with the source.

Merobix is not affiliated with, endorsed by, or sponsored by these organizations; their names are used only to identify the standards and products discussed.

More in Industrial Protocols
Modbus Illegal Function (Exception 01)  •  Modbus Function Code  •  Modbus Function Code 01 Read Coils  •  Modbus Function Code 02 Read Discrete Inputs  •  Modbus Function Code 03 Read Holding Registers  •  All Industrial Protocols →
Free SCADA operator training
Merobix University - 70 video lessons & 261 quiz questions, from first login to compliance reporting. No demo call required.
Start free →