Response Headers

A fixed 32-byte frame. The first sixteen bytes are the same for every encryption type; the last sixteen are how the server proves the response is genuine, and those differ by type.

Bytes 0–15: the same for every type

BytesFieldMeaning
0RIThe responding RAIDA's index, or a Content Server's node ID echoed back under type 9.
1SHShard ID. Zero.
2STStatus code. The single most important byte in the response. 250 is success; everything else is documented on the command's own page.
3CGCommand group, echoed from the request.
4–5FCFrame count. Always 1.
6–7ECClient echo, returned from request bytes 30–31. Types 8 and 9 always send zero here — the echo is deferred in both specifications.
8RSReserved, zero. The object transfer commands (6/76–84) overload this as a framing version.
9–11BLResponse body length, 24-bit big-endian. Note this is a different width from any request length field.
12–15ETServer execution time, 32-bit big-endian microseconds. The object transfer commands repurpose these bytes as part of a 32-bit body length.

Types 0, 1, 2 — bytes 16–31 carry a challenge proof

RI0SH1ST2CG3FC4EC6RS8BL (24-bit)9ET (exec time)12CH (Challenge proof)16CH (Challenge proof continues)24

The server returns a 16-byte value derived from the challenge the client sent in its request body. Under type 0 this is the challenge echoed back; under types 1 and 2 it is a proof combining the challenge with the key coin's authenticity number — something only a server that genuinely holds that AN could produce.

This is the older authentication model: the header proves the responder is genuine, while the body's integrity rests on the challenge CRC32. It is not authenticated encryption, and it does not detect tampering with the response body itself.

Types 8 and 9 — bytes 16–31 carry a GCM tag

RI0SH1ST2CG3FC4EC=06RS8BL (24-bit)9ET (exec time)12AT (GCM Auth Tag)16AT (GCM Auth Tag continues)24

The same sixteen bytes now hold the response's AES-256-GCM authentication tag. This is a genuine upgrade rather than a relabelling: the tag covers both the header and the response body, so a client that verifies it knows the entire response is untampered, not merely that the responder knew a secret.

PropertyValue
Response AADResponse header bytes 0–15
Tag positionBytes 16–31, full 16 bytes
KeySame key as the request
NonceNot transmitted. Derived locally from the request nonce.

Why the response nonce is not on the wire

The response nonce is the request nonce with its direction bit set: requests have the most significant bit of the nonce's first byte at 0, responses at 1. This partitions the nonce space so a request nonce and a response nonce can never collide under the same key — which is the property GCM requires.

The practical consequence for a client: keep the request nonce until the response has been verified. You cannot recover it from the response.

Reusing the 32-byte legacy frame for a modern AEAD cipher was deliberate. It meant type 8 could ship without changing the transport layer or any response parser — the frame is the same size and shape, and only the meaning of the last sixteen bytes changed.

The unauthenticated failure frame

A zero tag means the server could not authenticate you

When a type 8 or type 9 request cannot be authenticated at all — the key coin is unknown, the session handle does not resolve, or the GCM tag fails to verify — the server has no shared key, and therefore cannot produce a valid tag. It returns a fixed 32-byte frame with bytes 16–31 all zero and a zero body length.

Clients MUST handle this case explicitly. Do not treat a failed tag verification as a network error or a corrupt packet: check for the all-zero tag with a zero body length first, and read the status byte, which carries the real reason.

Type 9 defines named statuses for these conditions, including unknown handle (102), counter replay (103), capacity (104), authentication failed (105) and malformed (106).

Parsing pitfalls

TrapWhat to do
Assuming the body length is 16-bit because request lengths often areThe response length is 24-bit, at bytes 9–11. It matches no request length field in the protocol.
Expecting your echo bytes back under type 8 or 9They are always zero. Match requests to responses by connection, not by echo.
Discarding the request nonce after sendingYou need it to derive the response nonce. Keep it until verification completes.
Treating a zero tag as corruptionIt is a defined failure frame. Read the status byte.
Reading bytes 8 and 12–15 as reserved and execution time for object transfer commandsCommands 6/76–84 repurpose them for extended framing. See the object transfer pages.