Chapters

7 CoAP Exchange Reliability Contracts

coap
message-types
reliability
exchanges

A battery valve sends a CoAP request over a lossy radio and waits for an acknowledgement that may never arrive. Confirmable and non-confirmable messages express different reliability choices, while message IDs and tokens connect protocol events. The application must decide what a retry means for the physical valve.

For this reliability contract, CoAP means Constrained Application Protocol. A protocol is a rule for message exchange, and a payload is the application data carried by that exchange.

7.1 Separate the Exchange From the Valve Action

Start with Figure 7.1. Read the confirmable, non-confirmable, acknowledgement, and reset types with their direction. A confirmable message asks the peer to acknowledge the exchange. A non-confirmable message does not create that acknowledgement duty. Reset says a message was received but could not be processed in the expected context.

Figure then follows one request and its response. Note message ID, token, retransmission interval, acknowledgement, and any separate response. The message ID supports duplicate detection for the message exchange. The token lets a client match a response to its request. Neither identifier alone proves that a physical command is safe to repeat.

Suppose a client sends confirmable request message ID 4102 with token 7a to set a valve target to 30%. The valve applies the target and sends an acknowledgement, but that packet is lost. The client retransmits message ID 4102. Duplicate handling should return the prior exchange result without applying a second non-idempotent action. A command identifier in the application payload gives longer-lived protection when protocol duplicate state expires.

Use the retransmission timing configured for the test rather than assuming a fixed network value. If the first wait is 2 s and each retry doubles it, waits before three retries are 2 s, 4 s, and 8 s, totalling 14 s. Record actual randomized timeout behavior and the final application deadline. A safety system may need local fallback long before the exchange gives up.

Non-confirmable telemetry can be suitable when new samples replace old ones and occasional loss is acceptable. It is unsuitable when the application interprets silence as success. Confirmable delivery improves evidence that the peer received a message, but the response code and device state must still show whether the requested operation was accepted.

Predict the packet trace. Lose the first acknowledgement and expect the same message ID to repeat. Return reset and expect the exchange to stop with a visible error. Delay a separate response and verify the token still matches it. Finally repeat the valve command after protocol duplicate state is cleared and confirm the application identifier prevents an unintended second action.

7.2 Start With the Lost ACK

Prove a Retry Does Not Repeat the Action

Picture a valve that opens once, even though its reply disappears and the client sends the command again. A protocol means agreed rules and message order for communication. Constrained Application Protocol (CoAP) is a web-style method made for small devices and limited networks.

Name the request, Message ID, Token, action, reply, and retry timer. Test a normal reply, a lost acknowledgement, a duplicate request, and a delayed separate response.

Keep packet times, identifiers, server decisions, action count, and final response. This proves one exchange and duplicate rule, not every loss pattern; the deeper sections define message types, timing, correlation, and reset behavior.

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.

7.3 Learning Objectives

After this page, you should be able to:

  • Separate CoAP message-layer type from request/response Code and Token semantics in a packet trace.
  • Set CON/NON policy and document ACK timeout, randomization, backoff, and retransmission evidence.
  • Distinguish piggybacked ACK-plus-response exchanges from separate responses that use a new Message ID.
  • Diagnose duplicate suppression, Message ID reuse, Token correlation, and RST paths after context loss.

7.4 Why This Contract Comes After Message Types

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.

Overview: Four Message Types Living in Two Layers

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.

The four message types become clearer when placed into complete exchanges rather than memorised as abbreviations. Inspect Figure 7.1 before deciding which delivery contract fits a request and how long the server may take to answer.

CoAP exchange patterns showing a confirmable request with acknowledgment, a non-confirmable message, a piggybacked response, and a separate response.
Figure 7.1: CoAP reliable, fire-and-forget, piggybacked, and separate exchange patterns.

The top row of Figure 7.1 contrasts Confirmable / Reliable, where a CON Request receives an ACK Response, with Non-Confirmable / Fire-and-forget, where the NON Message has no return arrow. The lower Piggybacked / Inline response exchange carries ACK 2.05 + Data in one return packet. By contrast, Separate / Deferred response first sends ACK (empty), later delivers CON 2.05 + Data, and requires a final ACK. Those sequences keep delivery timing separate from the GET or PUT meaning assigned at the request/response layer.

Confirmable (CON)

Elicits an ACK and is retransmitted on timeout. Use for commands, writes, and any message whose loss would leave wrong device state.

Non-confirmable (NON)

No ACK and no retransmission. Use for frequent, replaceable readings where the next sample corrects any loss.

Acknowledgment (ACK)

Confirms exactly one CON by echoing its Message ID. It may be empty, or it may piggyback the response.

Reset (RST)

Signals that a received message could not be processed for lack of context. It also answers a CoAP ping (an empty CON).

Practitioner: Reliability Is a Per-Message Decision With Named Timers

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.

Worked Example: Valve Command vs Temperature Stream

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.

Attempt
Timer (from RFC 7252)
Approx. wait before retry
Outcome if ACK still lost
Initial send
random(ACK_TIMEOUT, ACK_TIMEOUT × 1.5)
2 to 3 s
Retransmit #1
Retransmit 1
timeout doubles
4 to 6 s
Retransmit #2
Retransmit 2
timeout doubles
8 to 12 s
Retransmit #3
Retransmit 3 / 4
doubles until MAX_RETRANSMIT = 4
up to ~45 s total (MAX_TRANSMIT_SPAN)
Give up; report delivery failure to the app

Practitioner Checklist

Start with the cost of failure: choose CON only when silent loss is unacceptable, because one exchange can consume four retransmissions of radio-on time. Let CoAP's exponential backoff own those retries rather than layering an application retry over the same message. Account for NSTART = 1 as well; confirmable writes to one peer serialize, so the latency budget must cover the queue. When the requirement is merely peer liveness, use an empty CON as a CoAP ping and expect a healthy peer to answer with RST instead of constructing a full resource request.

Under the Hood: Piggybacked vs Separate Responses, and Duplicate Suppression

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.

ServerClientServerClientPiggybacked (answer ready now)Separate (server needs time)CON GET (MID, Token)ACK 2.05 Content (same MID, Token)CON GET (MID, Token)ACK (empty)CON 2.05 Content (new MID, same Token)ACK

The difference between a piggybacked and separate response becomes clear when Figure is read with Message ID and Token as two distinct threads.

CoAP message exchange showing header, token, options, and payload fields carried between client and server.
The Message ID ties an ACK to its CON at the messaging layer; the Token ties a response to its request at the request/response layer, which is what makes separate responses possible.
  1. Broker Bex: Bex brings a request card with two distinct shape tokens to a sleepy sensor counter.

    A slow request arrives with a message number and token.

  2. Broker Bex: The counter returns a blank receipt carrying the request-number shape while the answer tray stays empty.

    An empty acknowledgement stops the request from being sent again.

  3. Broker Bex: Bex waits beside the working sensor while holding the other matching shape token.

    The sensor works. Bex keeps the request token safe.

  4. Broker Bex: A fresh envelope with a new number shape carries the result and the original request-token shape.

    The result returns in a new message with the same token.

  5. Broker Bex: The client returns a small receipt for the result envelope; the two message exchanges remain visibly separate.

    If that new message asks, the client confirms it too.

CW-0007 walkthrough: A slow server first confirms the request message, then returns the result in a new message whose matching token links it to the request.

In Figure, first follow the Message ID that pairs a CON with its ACK. Then follow the Token that pairs the application response with the original request. A ready response can ride inside the ACK; a delayed response uses a new message exchange but retains the Token. This separation also explains why duplicate suppression is keyed at the message layer while application correlation survives across exchanges.

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.

Piggybacked

ACK carries the response. Same Message ID as the request, Token matches. Used when the answer is immediate.

Separate

Empty ACK stops retransmission, then a new CON/NON carries the response, correlated only by Token.

Message ID

16-bit field that pairs ACK/RST with a specific CON/NON and drives duplicate detection.

Dedup window

Servers remember Message IDs for about EXCHANGE_LIFETIME so a retransmitted CON is answered, not re-executed.

7.5 Release Checklist

Before signing off a CoAP message-flow design, verify that:

Read these points as one connected sequence: start with Each interaction names the Type, Code, Message ID, Token, and CON/NON policy; then ACK timeout, ACK random factor, maximum retransmits, and any NSTART change are recorded with their rationale; then Piggybacked and separate response cases are distinguished, including when an empty ACK is sent; then Duplicate cache lifetime, Message ID reuse policy, and non-idempotent operation handling are explicit; then RST behavior is defined for unknown tokens, lost Observe state, rebooted endpoints, and malformed messages; and finish with The energy budget explains which traffic is allowed to be NON and what loss rate the application tolerates.

  • Each interaction names the Type, Code, Message ID, Token, and CON/NON policy.
  • ACK timeout, ACK random factor, maximum retransmits, and any NSTART change are recorded with their rationale.
  • Piggybacked and separate response cases are distinguished, including when an empty ACK is sent.
  • Duplicate cache lifetime, Message ID reuse policy, and non-idempotent operation handling are explicit.
  • RST behavior is defined for unknown tokens, lost Observe state, rebooted endpoints, and malformed messages.
  • The energy budget explains which traffic is allowed to be NON and what loss rate the application tolerates.

7.6 See Also

Read these points as one connected sequence: start with CoAP Message Types: Return to the main CON, NON, ACK, and RST chapter; then CoAP Message Format: Review the fields that carry Type, Code, Message ID, Token, options, and payload; then CoAP Method Codes and Multicast Contracts: Connect message reliability to method safety, idempotency, and multicast behavior; then CoAP Observe Registration and Freshness Contracts: Apply Message ID, Token, and RST behavior to long-running Observe relationships; and finish with CoAP Implementation Stack Trace Contracts: Check how library APIs expose retries, tokens, timeouts, and message types.

7.7 Next

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.