Confirmable (CON)
Elicits an ACK and is retransmitted on timeout. Use for commands, writes, and any message whose loss would leave wrong device state.
A Confirmable command can be delivered, executed, and still look failed if the ACK disappears on the way back. The client retries; the server must recognize the duplicate; the response still needs to match the original request instead of running the command twice.
This contract page follows that failure path. It separates Message ID, Token, timers, duplicate suppression, piggybacked responses, separate responses, and Reset so a trace review can prove what happened.
After this page, you should be able to:
CoAP Message Types introduces CON, NON, ACK, and RST as the four exchange types used by constrained devices. This page narrows in on the reliability contract behind those labels: which layer a field belongs to, how long a sender waits before retrying, how a delayed response is matched to its request, and how a server avoids executing the same Confirmable request twice.
The CoAP message story remains two-layered: Message ID proves delivery behavior, while Token and Code prove the request/response relationship.
Use it when you are reviewing traces, sizing retry windows for sleepy devices, deciding which messages are allowed to be NON, or debugging why a rebooted endpoint answers with Reset instead of a normal acknowledgment.
CoAP (RFC 7252) splits every exchange into two layers. The messaging layer handles the datagram itself and uses four message types plus a 16-bit Message ID. The request/response layer handles application meaning with a Method or Response Code plus a Token. The message type is orthogonal to whether a datagram carries a request or a response: a single message is both a type (CON/NON/ACK/RST) and, usually, a request or response.
Confirmable (CON) asks for reliability: the sender expects an acknowledgment and will retransmit if none arrives. Non-confirmable (NON) is fire-and-forget: no acknowledgment, no retransmission. Acknowledgment (ACK) confirms one specific CON by echoing its Message ID. Reset (RST) says "I received your message but cannot process it" — for example when a node reboots and loses the context for an ongoing exchange.
A useful packet-trace habit is to name both layers for every datagram. Type=CON, Code=0.01 is a confirmable GET request; Type=ACK, Code=2.05 is a piggybacked Content response; Type=ACK, Code=0.00 is an empty acknowledgment that only stops retransmission; and Type=RST, Code=0.00 rejects an unexpected or unprocessable message. Looking at only the Code hides the reliability behavior.
Keep this straight: CON and NON are how you ask a resource question; ACK and RST are how the network layer reacts to a CON. A reading sent as NON is never retransmitted, so the next sample is your only recovery.
Elicits an ACK and is retransmitted on timeout. Use for commands, writes, and any message whose loss would leave wrong device state.
No ACK and no retransmission. Use for frequent, replaceable readings where the next sample corrects any loss.
Confirms exactly one CON by echoing its Message ID. It may be empty, or it may piggyback the response.
Signals that a received message could not be processed for lack of context. It also answers a CoAP ping (an empty CON).
When you mark a message CON, you inherit RFC 7252's retransmission machinery, and its constants are worth knowing by name. The first retransmission timeout is a random value between ACK_TIMEOUT (default 2 s) and ACK_TIMEOUT × ACK_RANDOM_FACTOR (default 1.5, so up to 3 s). The timeout then doubles on each retry — binary exponential backoff — for up to MAX_RETRANSMIT (default 4) attempts. That yields a worst-case window of roughly 45 seconds (MAX_TRANSMIT_SPAN) before the sender gives up on that Message ID.
By default NSTART = 1, meaning an endpoint keeps only one CON exchange outstanding to a given destination at a time. This is deliberate congestion control for constrained links: a device cannot flood a sleepy peer with parallel confirmable traffic. If you need concurrency, you either raise NSTART carefully or use NON for the bulk traffic.
A controller issues PUT /actuators/valve as CON because a lost "close valve" command is unsafe. The same node reports /sensors/temp every 10 seconds as NON because the next reading replaces the last. If the valve ACK is lost, the timeline below plays out; the temperature NON simply relies on the next sample.
A server has two ways to answer a Confirmable request. In a piggybacked response, the ACK itself carries the answer: the same ACK that stops retransmission also holds the response code and payload (for example 2.05 Content). The ACK reuses the request's Message ID, and the Token matches the request's Token. This is the common case when the server can answer right away.
In a separate response, the server first returns an empty ACK (message code 0.00) to stop the client retransmitting, then sends the actual response later in a brand-new message — a fresh CON or NON with its own Message ID. The client recognizes it as the answer because the Token matches the original request. If that later message is CON, the client ACKs it in turn. Separate responses exist for resources that need time: waking a sensor, running a measurement, or querying a back-end.
sequenceDiagram
participant C as Client
participant S as Server
Note over C,S: Piggybacked (answer ready now)
C->>S: CON GET (MID, Token)
S-->>C: ACK 2.05 Content (same MID, Token)
Note over C,S: Separate (server needs time)
C->>S: CON GET (MID, Token)
S-->>C: ACK (empty)
S->>C: CON 2.05 Content (new MID, same Token)
C-->>S: ACK
Because a CON can be retransmitted, a server may receive the same message twice. CoAP handles this with deduplication: the server tracks recently seen Message IDs per source endpoint for about EXCHANGE_LIFETIME (roughly 247 seconds with default timers). A duplicate CON must not be acted on twice; instead the server resends the cached ACK. This matters most for non-idempotent operations — a duplicated POST that appended a log entry, or a relative counter increment, would be wrong if processed twice.
ACK carries the response. Same Message ID as the request, Token matches. Used when the answer is immediate.
Empty ACK stops retransmission, then a new CON/NON carries the response, correlated only by Token.
16-bit field that pairs ACK/RST with a specific CON/NON and drives duplicate detection.
Servers remember Message IDs for about EXCHANGE_LIFETIME so a retransmitted CON is answered, not re-executed.
Before signing off a CoAP message-flow design, verify that:
After you can read a message exchange at both layers, continue with CoAP Message Format to inspect the exact bits and option fields carried in each datagram.