Summary

  • In CoAP over UDP, Message ID handles duplicate detection and ACK/Reset correlation; Token, together with endpoint context, matches a response to an outstanding request. The two fields are deliberately separate.
  • A matching Token is a correlation receipt, not proof of a human, device owner, authenticated principal, authorization decision, current resource state or completed application action.

A client sends a request to a constrained device. The response comes back with the same short sequence of bytes the client placed in the Token field. In a trace, the match looks satisfying: request here, response there, identical Token between them. It is tempting to write one generous log message—transaction verified—and move on.

That sentence spends evidence the protocol never supplied.

The Token tells the client which outstanding request a response belongs to. It does not tell the client who owns the endpoint, who is standing behind a gateway, whether the request was authorized, whether a sensor’s value is fresh, or whether an actuator finished the physical action implied by a success code. Even its anti-spoofing role is bounded: randomized Tokens make blind guessing harder when transport security is absent. They do not become credentials.

Carsten Bormann’s documented place in this design is precise. He is one of three authors of RFC 7252, the 2014 Standards Track definition of CoAP. He is the first-listed author of RFC 8323, which carries CoAP over TCP, TLS and WebSockets. The first document separates Message ID from Token. The second performs a revealing subtraction: when a reliable transport takes responsibility for retransmission and duplicate handling, CoAP removes Message ID but keeps Token.

One number disappears. The other remains. That is an unusually clean experiment in what each field actually does.

Two small fields, two different clocks

CoAP was designed for nodes and networks where every byte matters. Over UDP, its fixed header includes a 16-bit Message ID. RFC 7252 assigns that value to the message layer. It helps detect duplicate messages and matches an Acknowledgement or Reset to the Confirmable or Non-confirmable message that prompted it. The matching rule includes the corresponding endpoint, and the same Message ID cannot be reused with that endpoint during the exchange lifetime.

This state has a short operational clock. A Confirmable message may be retransmitted because its acknowledgement was lost. The receiver can see the same Message ID from the same source endpoint more than once. It should acknowledge each copy while normally processing the enclosed request or response only once. The Message ID therefore helps answer a bounded question: have I seen this message exchange already, and does this ACK or Reset belong to it?

Token operates at the request/response layer. The client creates it; a server echoes it unchanged in the resulting response. RFC 7252 calls it a client-local identifier for differentiating concurrent requests and observes that it could have been called a request ID. Tokens currently in use should be unique for a source/destination endpoint pair, not for the Internet, an organisation or a person.

Its clock can outlive one datagram exchange. A Confirmable request may receive a piggybacked response in its ACK, but a response can also arrive separately. Message ID correlates the message mechanics. Token follows the semantic request into whatever valid response form comes back.

The fields sometimes appear together, but co-presence is not equivalence. In a piggybacked response, Message ID and Token both match because the acknowledgement and response share a message. In a separate response, Token is the request/response link; the new message runs its own message-layer exchange.

The error begins when an observability system stores both under one generic correlation_id. The database may become tidier, but the investigator loses which clock expired, which endpoint scope applied, which reuse rule mattered, and whether a duplicate verdict was about a datagram or an application operation.

RFC 8323 removes the ambiguity by removing a field

CoAP over TCP does not need its UDP message layer to retransmit or deduplicate. TCP supplies reliable ordered bytes, while CoAP adds framing for message boundaries. RFC 8323 therefore removes the Type and Message ID fields from the CoAP frame over reliable transports.

Token stays.

That is not an implementation convenience hidden in an appendix. It is a test of architectural responsibility. If Message ID were the identifier of the application transaction, removing it would break request/response matching. It does not, because Token owns that task. If Token were merely another duplicate marker, it could disappear with Message ID. It does not, because reliable transport does not know which CoAP response satisfies which CoAP request.

The comparison gives an operator a useful diagnostic. When a problem occurs only on UDP, inspect retransmission, exchange lifetime, Message ID reuse, duplicate cache and ACK/Reset handling. When it occurs on UDP and a reliable transport, move upward: outstanding-request state, Token generation and matching, endpoint or connection binding, intermediaries, response processing and application state. Transport differences become a way to localise a fault rather than a reason to flatten telemetry.

They also set a limit. A TCP or TLS connection can supply a stronger channel context than an unauthenticated UDP tuple, depending on configuration. It still does not make the Token itself an identity. The security association and the Token are joined evidence with different authors and lifetimes.

A random Token closes one door, not the building

RFC 7252 recommends a nontrivial randomized Token for a client that is not using transport-layer security. A client on the general Internet should use at least 32 bits of randomness, scaled to its threat model. The reason is response spoofing: an off-path attacker who cannot guess the Token is less likely to inject a reply that the client accepts as belonging to an outstanding request.

Message ID helps little here because it is usually sequential and guessable, and an attacker can send a separate response that does not rely on the request’s Message ID. This is another clean division. Message ID is useful for the duplicate and acknowledgement machine. Token randomness adds a request-correlation challenge against blind injection.

But a successful match proves only that the response carried a value sufficiently difficult for the attacker to guess under the assumed observation model. An on-path observer may see it. A compromised intermediary may possess the state. A weak generator may repeat it. A stale request table may accept it under the wrong lifetime. None of those questions is answered by renaming the Token an authentication token.

The receiving endpoint must treat a Token it did not generate as opaque. A server echoes bytes; it does not interpret them as a username, session authority or customer account. The client may attach local meaning to its own value, but that meaning is not automatically shared by any other hop.

An audit should therefore record the random-generation policy, Token length, reuse scope, endpoint binding and outstanding-request lifetime. It should record the security mode separately. If privacy matters, the telemetry may preserve a keyed digest rather than raw Token bytes, provided the method still supports the required join. “Token matched” and “peer authenticated” must remain two fields even when both are true.

A proxy does not carry one universal Token across the path

The word endpoint is easy to read as if it named a stable machine. In deployed constrained systems, a request may pass through forward proxies, reverse proxies, gateways, address translators and transport changes. CoAP Tokens are hop-by-hop.

An intermediary commonly keeps the client-side Token and transport address while issuing its own request upstream with its own Token. When the origin’s response arrives, the intermediary recovers the downstream mapping and constructs the appropriate response for the client. The same application journey can therefore contain several Token namespaces, several endpoint contexts and more than one timeout.

This matters for incident attribution. A Token seen on the device-facing hop may never have appeared on the client-facing hop. A gateway log that exposes only its upstream Token cannot name the downstream requester. A match at one hop does not prove that the next hop preserved the right mapping. The minimum useful record includes the observation point and a privacy-safe local join between the two hop records.

If the system writes one “global transaction ID” after the fact, it should be honest about its origin. That ID is an observability construct created by the operator, not a wire-level fact supplied end to end by CoAP. Its trust depends on the mapping code, clock, storage and access controls that produced it.

Putting request state into the Token changes custody, not truth

RFC 8974 explores a later technique: a client can serialize parts of its per-request state into the Token and recover them when the server echoes the value. Longer Tokens make more state portable. The document’s authors are Klaus Hartke and Michael Richardson, not Carsten Bormann; its relevance here is as a stress test of the earlier field boundary.

The document puts “stateless” in quotation marks for good reason. A client may avoid keeping a record for each request, yet it still needs per-server state, Token-generation state and congestion-control state. Confirmable UDP messages still need message-exchange state. A client that depends on extended Tokens must first discover support in a stateful exchange unless another reliable mechanism supplies that knowledge.

Serialization also converts a private table row into bytes that travel. Integrity protection becomes essential. Replay protection, freshness and privacy must be considered. Format changes need version separation. A maliciously large Token can consume scarce memory. A chain of “stateless” intermediaries can make Tokens grow as each hop serializes more client information.

The server remains an echo point. It need not understand the state inside the Token. The returning value lets the client reconstruct its own prior context; it does not make the server the issuer of that context and does not certify its truth. State has changed custody—from local memory to an opaque round trip—but responsibility has not disappeared.

This is the same institutional mistake found outside protocol engineering. Moving a fact into a shared record can make it portable and reviewable. It does not grant the record authority over the actor whose state it describes. A ledger entry, a Token and an RFC can each coordinate. None becomes a principal merely because other systems depend on it.

Build a receipt that does not overclaim

A useful CoAP receipt starts with where and when the packet or frame was observed. It names the transport and endpoint or connection context. It records the security mode and authenticated peer claim, if one exists, without copying that claim into the Token field.

For UDP, it retains message type, Message ID, exchange lifetime, retransmission count and duplicate-processing verdict. For every transport, it retains Token length and a safe representation of the value, the request method and target, the local outstanding-request record, the response code and the result of matching. At an intermediary, it links downstream and upstream records without pretending the wire carried a universal identifier.

Then it continues past the protocol. Which authorization decision admitted the operation? Which resource version did the response describe? Did an application transaction commit? Did a physical actuator acknowledge completion through an independent signal? Which software and configuration revisions make the receipt stale?

Those questions cannot be answered by a single field because they belong to different actors. The client owns correlation state. The transport and CoAP message layer own delivery mechanics. The security layer owns its peer claim. The server owns authorization and resource processing. An application or device owner owns outcome evidence. The IETF specifies interoperable behaviour; it does not operate the deployment.

Carsten Bormann’s role is evidence, not mandate

The current IETF profile lists Bormann as a chair of the CoRE working group and the Thing-to-Thing Research Group and lists 65 RFCs. Those facts describe a substantial contribution record at the time of review. They do not turn one contributor into the owner of consensus, a deployed implementation or an operator’s risk decision.

The stronger attribution is narrower. RFC 7252 records Bormann among the authors who specified the separation. RFC 8323, with Bormann first in the author list, demonstrates how that separation survives a change of transport. The documents are IETF products, publicly reviewed and approved through a collective process.

Running code supplies the next piece of evidence. A conforming parser, a Token generator with measured randomness, a duplicate cache, a correctly bound security association, a gateway mapping and an application receipt show what a particular system adopted. The publication date of a standard cannot replace those observations.

That restraint is not a reduction of engineering credit. It is the engineering contribution itself. A compact protocol succeeds when it says exactly enough for independent systems to interoperate, then stops before its fields are used to claim identities, permissions and outcomes they were never designed to carry.

The Token matched a reply. The operator still has to prove the rest.

Sources