Concise Binary Object Representation (CBOR)
Extracted elements (33)
CBOR extends the JSON data model—not the JSON grammar—to add binary byte strings and other types while allowing multiple serializations of the same value. Extensibility via IANA-registered tags and simple values eliminates the need for version negotiation; unknown tags and simple values can be forwarded by decoders that do not recognize them.
Preferred serialization always uses the shortest argument encoding and the shortest IEEE 754 floating-point format that preserves the value (e.g., 5.5 → 0xf94580 as binary16). This is not mandatory by default but is the baseline for deterministic encoding and minimizes encoded size.
The definition of new tags with serialization-order-dependent semantics (as with tag numbers 25 and 29) is NOT RECOMMENDED because such tags cannot be layered on top of arbitrary generic CBOR encoders/decoders and require deep integration into the codec, undermining CBOR's generic-encoder/decoder design goal.
CBOR's signed integer range for an 8-byte encoding is -2^64..2^64-1 (using the major type as sign bit), which is wider than the typical platform int64_t range (-2^63..2^63-1). Protocols using numbers near these boundaries should define handling for values outside the common platform range.
JavaScript and similar environments that represent all numbers as IEEE 754 binary64 may silently lose precision when decoding CBOR integers with more than 53 significant bits. CBOR-based protocols should define expectations for handling such nontrivial numbers in receiving applications.
RFC 8949 defines a 'length-first core deterministic encoding' variant that sorts map keys shorter-first, then bytewise lexicographic for equal-length keys—matching the 'Canonical CBOR' ordering from RFC 7049 Section 3.9. Protocols needing RFC 7049 compatibility should adopt this variant explicitly.
RFC 8949 obsoletes RFC 7049 with editorial improvements, new normative details, and errata fixes, but does not create a new version of the CBOR interchange format. All data items valid under RFC 7049 remain valid under RFC 8949.
An encoder MUST NOT issue two-byte sequences starting with 0xf8 (major type 7, additional information 24) and continuing with a byte less than 0x20 (32 decimal); such sequences are not well-formed, and each simple value such as false, true, null, or undefined has only a single one-byte representation.
An encoder MUST produce only well-formed encoded data items. A decoder MUST NOT return a decoded data item when it encounters input that is not a well-formed encoded CBOR data item.
CBOR-based protocols MUST specify how their decoders handle invalid and unexpected data, and MUST NOT be designed to make use of invalid items. Encoders for CBOR-based protocols MUST produce only valid items.
Core deterministic encoding MUST use preferred serialization (shortest argument and floating-point encoding), MUST NOT include indefinite-length items, and MUST sort map keys in bytewise lexicographic order of their deterministic encodings.
Streaming CBOR applications that present incremental data to an application MUST have a matching streaming security mechanism where the desired protection is available for the incrementally presented data.
Tag number 1 (epoch-based date/time) content MUST be an unsigned or negative integer (major types 0 or 1) or a floating-point number (major type 7 with additional info 25, 26, or 27); other contained types are invalid. Applications requiring times after early 2106 cannot omit 64-bit integer support.
The first protocol layer that processes the semantics of an invalid CBOR item MUST either replace it with an error marker and continue, or issue an error and stop processing. The protocol MUST specify which option applies for each kind of invalid item. Layers that do not process semantics MUST forward invalid data as-is.
CBOR defines eight major types: 0 (unsigned integer, value = argument), 1 (negative integer, value = -1 minus argument), 2 (byte string, argument = byte count), 3 (UTF-8 text string, argument = byte count), 4 (array, argument = item count), 5 (map, argument = pair count), 6 (tag, argument = tag number), 7 (simple values and floating-point).
Indefinite-length encoding is available for arrays, maps, byte strings, and text strings by setting additional information to 31. Items are terminated by the 'break' stop code (0xFF, major type 7, additional info 31). Indefinite-length encoding is not valid for major types 0, 1, or 6.
Simple values (major type 7, additional info 0–24) include false (20), true (21), null (22), and undefined (23). Values 0–19 and 32–255 are unassigned. Each simple value has exactly one encoding; two-byte sequences starting with 0xf8 followed by a byte < 0x20 are not well-formed.
Tag 55799 (self-described CBOR) serializes to the three-byte magic sequence 0xd9d9f7, chosen because it is not a valid start of any Unicode encoding and does not conflict with common file format signatures. It imparts no additional semantics to the enclosed item.
Tags (major type 6) associate semantic meaning with an enclosed data item via a registered tag number. Key tag numbers from RFC 7049 include: 0 (RFC 3339 date/time string), 1 (epoch-based date/time), 2/3 (unsigned/negative bignum), 4/5 (decimal fraction/bigfloat), 24 (embedded CBOR), 21–23 (expected base64url/base64/base16), 55799 (self-described CBOR).
RFC 8949 registers the 'application/cbor' media type (Section 9.3), updates the CoAP Content-Format Registry with content formats for application/cbor (Section 9.4), and registers the '+cbor' structured syntax suffix in the Structured Syntax Suffix Registry (Section 9.5).
The 'Concise Binary Object Representation (CBOR) Simple Values' registry (Section 9.1) tracks assignments of simple value numbers 0–255. Values 20–23 are assigned (false, true, null, undefined); values 24–31 are reserved; 0–19 and 32–255 are available for assignment.
The 'Concise Binary Object Representation (CBOR) Tags' registry (Section 9.2) tracks tag number assignments with a three-tier policy: tag numbers 0–23 require Standards Action, 24–32767 require Specification Required, and 32768 and above are First Come First Served.
Deeply nested CBOR structures and large indefinite-length items can cause resource exhaustion (stack overflow, excessive memory allocation) in decoders. Implementations should impose limits on nesting depth and item sizes, and streaming applications must account for the unbounded memory potentially required to buffer indefinite-length items.
Duplicate keys in a CBOR map can be exploited for security attacks when different decoders or processing layers resolve duplicates differently, leading to inconsistent interpretation of data. Protocols should mandate unique map keys and specify deterministic handling of duplicates.
Bignums (tag 2 = unsigned, tag 3 = negative) encode an arbitrary-precision integer as a byte string in network byte order. Tag 2 value is n; tag 3 value is -1-n. Leading zeros are permitted but not preferred. The preferred serialization uses basic integer major types 0/1 when the value fits.
Decimal fractions (tag 4) and bigfloats (tag 5) encode as a two-element array [exponent, mantissa]; tag 4 value is m*(10^e), tag 5 value is m*(2^e). The exponent MUST be encoded as major type 0 or 1; the mantissa may also be a bignum.
Each CBOR data item begins with an initial byte whose high-order 3 bits encode the major type (0–7) and whose low-order 5 bits encode additional information. Together with any following bytes needed to construct the unsigned integer argument, this is called the 'head' of the data item.
Indefinite-length byte and text strings consist of a header byte (major type with additional info 31), followed by zero or more definite-length string chunks of the same major type, terminated by 0xFF ('break'). Chunks must not be indefinite-length, and UTF-8 scalar values must not be split across chunk boundaries.
Major type 0 encodes unsigned integers 0..2^64-1 with the argument as the value. Major type 1 encodes negative integers -2^64..-1; the decoded value is -1 minus the argument (e.g., -500 encodes argument 499).
Major type 3 (text string) encodes the byte count in the argument followed by UTF-8 bytes (RFC 3629); Unicode characters are never escaped, so newline U+000A is always byte 0x0a. A string with invalid UTF-8 is well-formed but not valid.
Major type 5 (map) uses the argument to specify the number of key-value pairs, so 2N data items follow interleaved key-then-value. A map with an odd number of items (missing final value) is not well-formed. Duplicate keys make a map invalid though well-formed.
Major type 7 with additional information 25/26/27 encodes IEEE 754 half-precision (16-bit), single-precision (32-bit), or double-precision (64-bit) floating-point values in the following bytes. Additional info 0–23 encodes simple values directly; value 24 is a one-byte extension for simple values 32–255.
The 5-bit additional information field encodes the argument: values 0–23 are the argument itself; 24/25/26/27 indicate 1/2/4/8 following bytes in network byte order; values 28–30 are reserved and render the item not well-formed; value 31 signals indefinite-length encoding or the 'break' stop code.