Block2 (option 23)
Fragments a large response body. The client walks block 0, 1, 2, ... until the server clears the More flag.
The device asks for a firmware image, receives several blocks, loses one packet, then wakes later behind a proxy that may still have cached metadata. A working demo is not enough; the transfer needs block size, numbering, retry, resume, hash, discovery, and freshness evidence.
This contract page keeps those proof points together so block-wise transfer and resource discovery remain reviewable when the network is constrained and intermittent.
After this page, you should be able to:
/.well-known/core discovery, CoRE Link Format attributes, filtered discovery queries, and Content-Format 40.CoAP Advanced Features introduces block-wise transfer, resource discovery, transport alternatives, and security. This page narrows in on the contracts most likely to fail during implementation: block sizing, partial-transfer recovery, resource metadata, and cache freshness across proxies.
Keep the CoAP advanced context visible: these are still the advanced CoAP features from the parent chapter, only recast as evidence a reviewer can check.
Use it when a device downloads firmware, uploads logs, exposes /.well-known/core, advertises observable resources, or relies on a proxy to shield a sleepy origin from repeated reads.
CoAP normally puts one message in one UDP datagram. That is perfect for a temperature reading but hopeless for a firmware image or a large configuration document: those exceed what a single datagram can carry, and relying on IP-layer fragmentation is fragile on lossy constrained links because losing one fragment discards the whole packet. Block-wise transfer (RFC 7959) solves this at the CoAP layer by splitting a single logical transfer into numbered blocks.
The key benefit is failure isolation. Each block is carried in its own request/response exchange with its own Message ID, so a lost block is retransmitted alone rather than forcing the entire payload to restart. Two options drive it: Block2 (option 23) governs a large response body, such as a big GET result, and Block1 (option 27) governs a large request body, such as a PUT or POST upload.
In a real maintenance window, that isolation changes the rollout plan. Suppose a pump controller downloads a 96 KB safety-profile image over a 6LoWPAN mesh using 256-byte Block2 chunks. The transfer has 384 numbered blocks. If interference drops block 177, the controller repeats only GET Block2:177; blocks 0 through 176 stay valid in the reassembly buffer. The review evidence should record the chosen block size, retry cap, resume point, hash check, and the condition that triggers rollback to the previous profile.
Fragments a large response body. The client walks block 0, 1, 2, ... until the server clears the More flag.
Fragments a large request body for PUT/POST uploads, one block per message.
Each block is its own exchange, so loss costs one block, not the whole transfer.
Splitting at the CoAP layer avoids brittle IP fragmentation on constrained networks.
A Block1 or Block2 option value packs three fields. NUM is the block number within the transfer. M (the More flag) is 1 while further blocks follow and 0 on the last block. SZX is a 3-bit size exponent, and the block size is 2^(SZX + 4) bytes — so SZX 0 is 16 bytes, SZX 4 is 256 bytes, and SZX 6 is the maximum 1024 bytes. Either endpoint can negotiate down to a smaller SZX if its buffers are tight; the smallest size that both accept wins.
For a concrete encoding check, take an 18 KB log upload from a meter concentrator. With SZX 4 the client sends 256-byte Block1 chunks, so it needs ceil(18,432 / 256) = 72 blocks. Block 31 carries NUM=31, M=1, and SZX=4; the last block carries NUM=71, M=0, and the same SZX unless the server negotiated down. A good trace review checks those fields against the byte offsets rather than trusting the library call.
For a large upload, the client sends Block1 blocks and the server answers each non-final block with 2.31 Continue, meaning "block stored, send the next," then returns 2.01 Created or 2.04 Changed on the last block. If blocks arrive out of order or a needed one is missing, the server replies 4.08 Request Entity Incomplete; if a block exceeds what the server will accept it may reply 4.13 Request Entity Too Large, often carrying a smaller SZX hint. Pairing a transfer with an ETag lets both sides detect the resource changing mid-transfer so they do not stitch together inconsistent blocks.
Before a client can use a resource it usually has to find it. CoAP standardizes this with a well-known URI: a GET to /.well-known/core returns a document in the CoRE Link Format (RFC 6690), sent with Content-Format 40 (application/link-format). The body is a comma-separated list of links with attributes, for example </sensors/temp>;rt="temperature";if="sensor";ct=50;obs. Here rt is the resource type, if is the interface description, ct is the content-format the resource speaks (50 = JSON), and obs marks it observable. A client can narrow the query — GET /.well-known/core?rt=temperature returns only temperature links — which keeps discovery cheap on a large node.
Once resources are known, caching reduces how often a sleepy node is disturbed. Every response carries an implicit or explicit Max-Age (option 14, default 60 seconds) stating how long it stays fresh. A caching CoAP proxy — forward or reverse — can store a response and serve it to other clients until Max-Age expires, so ten dashboards observing one sensor need not each wake the device. When freshness lapses, an ETag (option 4) lets the proxy revalidate: it repeats the ETag, and if nothing changed the origin answers 2.03 Valid with no body, saving the payload entirely.
For example, a greenhouse gateway may discover </zone/3/temp>;rt="temperature";if="sensor";ct=60;obs and </zone/3/valve>;rt="irrigation";if="actuator";ct=50 from the same node. It can cache the temperature reading for 45 seconds because the sensor publishes slow environmental data, but it should not cache the valve control response as if it were harmless telemetry. The evidence record should show the discovery query, Link Format body, Max-Age value, ETag revalidation result, and which resources are excluded from shared caching.
The standard discovery endpoint returning a link-format list of a node's resources.
rt, if, ct, sz, and obs describe each resource so clients bind by capability, not guesswork.
A proxy reuses a stored response until Max-Age expires, sparing the origin device.
A repeated ETag lets the origin answer 2.03 Valid with no payload when nothing changed.
Before shipping a CoAP block-transfer or discovery design, verify these records:
/.well-known/core as Content-Format 40 with rt, if, ct, sz, and obs attributes where relevant.?rt=temperature and ?obs are tested on large nodes so clients avoid scanning irrelevant resources.2.03 Valid handling, and resources excluded from shared caching.Return to CoAP Advanced Features, then continue to CoAP Security and Applications for securing block transfers and discovered resources.