Appendix A: Tag-length-value (TLV) Encoding Format
A.1. Scope & Purpose
The Matter TLV (Tag-Length-Value) format is a generalized encoding method for simple structured data, used throughout this specification.
Values in the Matter TLV format are encoded as TLV elements. Each TLV element has a type. Ele ment types fall into two categories: primitive types and container types. Primitive types convey fun damental data values such as integers and strings. Container types convey collections of elements that themselves are either primitives or containers. The Matter TLV format supports three different container types: structures, arrays and lists.
All valid TLV encodings consist of a single top-level element. This value can be either a primitive type or a container type.
A.2. Tags
A TLV element includes an optional numeric tag that identifies its purpose. A TLV element without a tag is called an anonymous element. For elements with tags, two categories of tags are defined: profile-specific and context-specific.
A.2.1. Profile-Specific Tags
Profile-specific tags identify elements globally. A profile-specific tag is a 64-bit number composed of the following fields:
- 16-bit Vendor ID
- 16-bit profile number
- 32-bit tag number
Profile-specific tags are defined either by Matter or by vendors. Additionally the Matter Common Profile includes a set of predefined profile-specific tags that can be used across organizations.
A.2.2. Context-Specific Tags
Context-specific tags identify elements within the context of a containing structure element. A con text-specific tag consists of a single 8-bit tag number. The meaning of a context-specific tag derives from the structure it resides in, implying that the same tag number may have different meanings in the context of different structures. Effectively, the interpretation of a context-specific tag depends on the tag attached to the containing element. Because structures themselves can be assigned con text-specific tags, the interpretation of a context-specific tag may ultimately depend on a nested chain of such tags.
Context-specific tags can only be assigned to elements that are immediately within a structure. This
implies that an element with a context-specific tag cannot appear as the outermost element of a TLV encoding.
A.2.3. Anonymous Tags
A special “anonymous tag” is used to denote TLV elements that lack a tag value. Such a TLV element is referred to as an anonymous element.
A.2.4. Canonical Ordering of Tags
Where a distinguished ordering of tags is required (e.g. for the purposes of generating a hash or cryptographic signature of elements within a structure), the following ordering rules SHALL be used:
- Anonymous tags SHALL be ordered before all other
- Context-specific tags SHALL be ordered before profile-specific
- Context-specific tags with numerically lower tag values SHALL be ordered before those with higher tag
- Profile-specific tags with numerically lower Vendor IDs SHALL be ordered before those with higher Vendor
- Profile-specific tags with the same Vendor ID, but numerically lower profile numbers SHALL be ordered before those with higher profile
- Profile-specific tags with the same Vendor ID and the same profile numbers but numerically lower tag numbers SHALL be ordered before those with higher tag
The ordering rules SHALL apply to elements at the same level within a container.
A.3. Lengths
Depending on its type, a TLV element may contain a length field that gives the length, in octets, of the element’s value field. A length field is only present for string types (character and octet strings). Other element types either have a predetermined length or are encoded with a marker that identi fies their end.
A.4. Primitive Types
The Matter TLV format supports the following primitive types:
- Signed integers
- Unsigned integers
- UTF-8 Strings
- Octet Strings
- Single or double-precision floating point numbers (following IEEE 754-2019)
- Booleans
- Nulls
Of the primitive types, integers, floating point numbers, booleans and nulls have a predetermined length specified by their type. Octet strings and UTF-8 strings include a length field that gives their lengths in octets.
A.5. Container Types
The Matter TLV format supports the following container types:
- Structures
- Arrays
- Lists
Each of the container types is a form of element collection that can contain primitive types and/or other container types. The elements appearing immediately within a container type are called its members. A container type can contain any number of member elements, including none. Con tainer types can be nested to any depth and in any combination. The end of a container type is denoted by a special element called the ‘end-of-container’ element. Although encoded as a member, conceptually the end-of-container element is not included in the members of the containing type.
A.5.1. Structures
A structure is a collection of member elements that each have a distinct meaning. All member ele ments within a structure SHALL have a unique tag as compared to the other members of the struc ture. Member elements without tags (anonymous elements) are not allowed in structures. The encoded ordering of members in a structure may or may not be important depending on the intent of the sender or the expectations of the receiver. For example, in some situations, senders and receivers may agree on a particular ordering of elements to make encoding and decoding easier.
Where a distinguished ordering of members is required (for example, for the purposes of generat ing a hash or cryptographic signature of the structure), the members of the structure SHALL be encoded as specified in Section A.2.4, “Canonical Ordering of Tags”.
A.5.2. Arrays
An array is an ordered collection of member elements that either do not have distinct meanings, or whose meanings are implied by their encoded positions in the array. An array can contain any type of element, including other arrays. All member elements of an array SHALL be anonymous ele ments – that is, they SHALL be encoded with an anonymous tag.
A.5.3. Lists
A list is an ordered collection of member elements, each of which may be encoded with a tag. The meanings of member elements in a list are denoted by their position within the list in conjunction with any associated tag value they may have.
A list can contain any type of element, including other lists. The members of a list may be encoded
with any form of tag, including an anonymous tag. The tags within a list do not need to be unique with respect to other members of the list.
A.6. Element Encoding
A TLV element is encoded a single control octet, followed by a sequence of tag, length and value octets. Depending on the nature of the element, any of the tag, length or value fields may be omit ted.
Control Octet | Tag | Length | Value |
1 octet | 0 to 8 octets | 0 to 8 octets | Variable |
A.7. Control Octet Encoding
The control octet specifies the type of a TLV element and how its tag, length and value fields are encoded. The control octet consists of two subfields: an element type field which occupies the lower 5 bits, and a tag control field which occupies the upper 3 bits.
A.7.1. Element Type Field
The element type field encodes the element’s type as well as how the corresponding length and value fields are encoded. In the case of Booleans and the Null value, the element type field also encodes the value itself.
Control Octet | Description | |||||||
Tag Control | Element Type | |||||||
7 | 6 | 5 | 4 | 3 | 2 | 1 | 0 | |
x | x | x | 0 | 0 | 0 | 0 | 0 | Signed Integer, 1-octet value |
x | x | x | 0 | 0 | 0 | 0 | 1 | Signed Integer, 2-octet value |
x | x | x | 0 | 0 | 0 | 1 | 0 | Signed Integer, 4-octet value |
x | x | x | 0 | 0 | 0 | 1 | 1 | Signed Integer, 8-octet value |
x | x | x | 0 | 0 | 1 | 0 | 0 | Unsigned Integer, 1-octet value |
x | x | x | 0 | 0 | 1 | 0 | 1 | Unsigned Integer, 2-octet value |
x | x | x | 0 | 0 | 1 | 1 | 0 | Unsigned Integer, 4-octet value |
x | x | x | 0 | 0 | 1 | 1 | 1 | Unsigned Integer, 8-octet value |
x | x | x | 0 | 1 | 0 | 0 | 0 | Boolean False |
x | x | x | 0 | 1 | 0 | 0 | 1 | Boolean True |
x | x | x | 0 | 1 | 0 | 1 | 0 | Floating Point Number, 4-octet value |
x | x | x | 0 | 1 | 0 | 1 | 1 | Floating Point Number, 8-octet value |
x | x | x | 0 | 1 | 1 | 0 | 0 | UTF-8 String, 1-octet length |
Control Octet | Description | |||||||
x | x | x | 0 | 1 | 1 | 0 | 1 | UTF-8 String, 2-octet length |
x | x | x | 0 | 1 | 1 | 1 | 0 | UTF-8 String, 4-octet length |
x | x | x | 0 | 1 | 1 | 1 | 1 | UTF-8 String, 8-octet length |
x | x | x | 1 | 0 | 0 | 0 | 0 | Octet String, 1-octet length |
x | x | x | 1 | 0 | 0 | 0 | 1 | Octet String, 2-octet length |
x | x | x | 1 | 0 | 0 | 1 | 0 | Octet String, 4-octet length |
x | x | x | 1 | 0 | 0 | 1 | 1 | Octet String, 8-octet length |
x | x | x | 1 | 0 | 1 | 0 | 0 | Null |
x | x | x | 1 | 0 | 1 | 0 | 1 | Structure |
x | x | x | 1 | 0 | 1 | 1 | 0 | Array |
x | x | x | 1 | 0 | 1 | 1 | 1 | List |
0 | 0 | 0 | 1 | 1 | 0 | 0 | 0 | End of Container |
x | x | x | 1 | 1 | 0 | 0 | 0 | Reserved (where xxx are not 000) |
x | x | x | 1 | 1 | 0 | 0 | 1 | Reserved |
x | x | x | 1 | 1 | 0 | 1 | 0 | Reserved |
x | x | x | 1 | 1 | 0 | 1 | 1 | Reserved |
x | x | x | 1 | 1 | 1 | 0 | 0 | Reserved |
x | x | x | 1 | 1 | 1 | 0 | 1 | Reserved |
x | x | x | 1 | 1 | 1 | 1 | 0 | Reserved |
x | x | x | 1 | 1 | 1 | 1 | 1 | Reserved |
For both signed and unsigned integer types the bottom two bits of the element type field signal the width of the corresponding field as follows:
- 00 — 1 octet
- 01 — 2 octets
- 10 — 4 octets
- 11 — 8 octets
For UTF-8 and octet string types the bottom two bits of the element type field signal the width of the length field as follows:
- 00 — 1 octet
- 01 — 2 octets
- 10 — 4 octets
- 11 — 8 octets
For end of container element type the tag control bits are set to 0. Any other combination of the tag control bits for this element type only is reserved. See Section A.10, “End of Container Encoding”.
A.7.2. Tag Control Field
The tag control field identifies the form of tag assigned to the element (including none) as well as the encoding of the tag octets.
Control Octet | Description | |||||||
Tag Control | Element Type | |||||||
7 | 6 | 5 | 4 | 3 | 2 | 1 | 0 | |
0 | 0 | 0 | x | x | x | x | x | Anonymous Tag Form, 0 octets |
0 | 0 | 1 | x | x | x | x | x | Context-specific Tag Form, 1 octet |
0 | 1 | 0 | x | x | x | x | x | Common Profile Tag Form, 2 octets |
0 | 1 | 1 | x | x | x | x | x | Common Profile Tag Form, 4 octets |
1 | 0 | 0 | x | x | x | x | x | Implicit Profile Tag Form, 2 octets |
1 | 0 | 1 | x | x | x | x | x | Implicit Profile Tag Form, 4 octets |
1 | 1 | 0 | x | x | x | x | x | Fully-qualified Tag Form, 6 octets |
1 | 1 | 1 | x | x | x | x | x | Fully-qualified Tag Form, 8 octets |
A.8. Tag Encoding
Tags are encoded in 0, 1, 2, 4, 6 or 8 octet widths as specified by the tag control field. Tags consist of up to three numeric fields: a Vendor ID field, a profile number field, and a tag number field. All fields are encoded in little-endian order. The tag fields are ordered as follows:
Vendor ID | Profile Number | Tag Number |
0 or 2 octets | 0 or 2 octets | 1, 2, or 4 octets |
A.8.1. Fully-Qualified Tag Form
A profile-specific tag can be encoded in fully-qualified tag form, where the encoding includes all three tag components (Vendor ID, profile number and tag number). Two variants of this form are supported, one with a 16-bit tag number and one with a 32-bit tag number. The 16-bit variant SHALL be used with tag numbers < 65536, while the 32-bit variant SHALL be used with tag num bers >= 65536.
Tag Control | Vendor ID Size | Profile Number Size | Tag Number Size | |
C0h | 2 octets | 2 octets | 2 octets | For tag numbers < 65536 |
Tag Control | Vendor ID Size | Profile Number Size | Tag Number Size | |
E0h | 2 octets | 2 octets | 4 octets |
For tag numbers >= 65536 |
A.8.2. Implicit Profile Tag Form
A profile-specific tag can also be encoded in implicit profile tag form, where the encoding includes only the tag number, and the Vendor ID and profile number are inferred from the protocol context in which the TLV encoding is communicated. This form also has two variants based on the magni tude of the tag number.
Tag Control | Tag Number Size | |
80h | 2 octets | For tag numbers < 65536 |
A0h | 4 octets | For tag numbers >= 65536 |
A.8.3. Common Profile Tag Form
A special encoding exists for profile-specific tags that are defined by the Matter Common Profile. These are encoded in the same manner as implicit profile tags except that they are identified as common profile tags, rather than implicit profile tags in the tag control field.
Tag Control | Tag Number Size | |
40h | 2 octets | For tag numbers < 65536 |
60h | 4 octets | For tag numbers >= 65536 |
A.8.4. Context-Specific Tag Form
Context-specific tags are encoded as a single octet conveying the tag number.
Tag Control | Tag Number Size | |
20h | 1 octets | All tag numbers 0 – 255 |
A.8.5. Anonymous Tag Form
Anonymous elements do not encode any tag octets.
Tag Control | Tag Size | |
00h | 0 octets | No data encoded |
A.9. Length Encoding
Length fields are encoded in 0, 1, 2, 4 or 8 octet widths, as specified by the element type field. Length fields of more than one octet are encoded in little-endian order. The choice of width for the
length field is up to the discretion of the sender, implying that a sender can choose to send more length octets than strictly necessary to encode the value.
A.10. End of Container Encoding
The end of a container type is marked with a special element called the end-of-container element. The end-of-container element is encoded as a single control octet with the value 18h. The tag con trol bits within the control octet SHALL be set to zero, implying that end-of-container element can never have a tag.
Control Octet |
1 octet |
A.11. Value Encodings
A.11.1. Integers
An integer element is encoded as follows:
Control Octet | Tag | Value |
1 octet | 0 to 8 octets | 1, 2, 4 or 8 octets |
The number of octets in the value field is indicated by the element type field within the control octet. The choice of value octet count is at the sender’s discretion, implying that a sender is free to send more octets than strictly necessary to encode the value. Within the value octets, the integer value is encoded in little-endian format (two’s complement format for signed integers).
A.11.2. UTF-8 and Octet Strings
UTF-8 and octet strings are encoded as follows:
Control Octet | Tag | Length | Value |
1 octet | 0 to 8 octets | 1 to 8 octets | 0 to 264-1 octets |
The length field of a UTF-8 or octet string encodes the number of octets (not characters) present in the value field. The number of octets in the length field is implied by the type specified in the ele ment type field (within the control octet).
For octet strings, the value can be any arbitrary sequence of octets. For UTF-8 strings, the value octets SHALL encode a valid UTF-8 character (code points) sequence. Senders SHALL NOT include a terminating null character to mark the end of a string.
A.11.3. Booleans
Boolean elements are encoded as follows:
Control Octet | Tag |
1 octet | 0 to 8 octets |
The value of a Boolean element (true or false) is implied by the type indicated in the element type field.
A.11.4. Arrays, Structures and Lists
Array, structure and list elements are encoded as follows:
Control Octet | Tag | Value | End-of-Container |
1 octet | 0 to 8 octets | Variable | 1 octet |
The value field of an array/structure/list element is a sequence of encoded TLV elements that consti tute the members of the element, followed by an end-of-container element. The end-of-container element SHALL always be present, even in cases where the end of the array/structure/list element could be inferred by other means (e.g. the length of the packet containing the TLV encoding).
A.11.5. Floating Point Numbers
A floating point number is encoded as follows:
Control Octet | Tag | Value |
1 octet | 0 to 8 octets | 4 or 8 octets |
The value field of a floating point element contains an IEEE 754-2019 single or double precision floating point number encoded in little-endian format (specifically, the reverse of the order described in External Data Representation, RFC 4506). The choice of precision is implied by the type specified in the element type field (within the control octet). The sender is free to choose either pre cision at their discretion.
A.11.6. Nulls
A Null value is encoded as follows:
Control Octet | Tag |
1 octet | 0 to 8 octets |
A.12. TLV Encoding Examples
In order to better ground the TLV concepts, this subsection provides a set of sample encodings. In the tables below, type and values column uses a decimal representation for all number whereas the encoding is represented with hexadecimal numbers.
Table 95, “Sample encoding of primitive types” shows sample encodings for primitive types. All examples in the table below are encoded as anonymous elements.
Table 95. Sample encoding of primitive types
Type and Value | Encoding (hex) |
Boolean false | 08 |
Boolean true | 09 |
Signed Integer, 1-octet, value 42 | 00 2a |
Signed Integer, 1-octet, value -17 | 00 ef |
Unsigned Integer, 1-octet, value 42U | 04 2a |
Signed Integer, 2-octet, value 42 | 01 2a 00 |
Signed Integer, 4-octet, value -170000 | 02 f0 67 fd ff |
Signed Integer, 8-octet, value 40000000000 | 03 00 90 2f 50 09 00 00 00 |
UTF-8 String, 1-octet length, “Hello!” | 0c 06 48 65 6c 6c 6f 21 |
UTF-8 String, 1-octet length, “Tschüs” | 0c 07 54 73 63 68 c3 bc 73 |
Octet String, 1-octet length, octets 00 01 02 03 04 | 10 05 00 01 02 03 04 |
Null | 14 |
Single precision floating point 0.0 | 0a 00 00 00 00 |
Single precision floating point (1.0 / 3.0) | 0a ab aa aa 3e |
Single precision floating point 17.9 | 0a 33 33 8f 41 |
Single precision floating point infinity (∞) | 0a 00 00 80 7f |
Single precision floating point negative infinity (-∞) | 0a 00 00 80 ff |
Double precision floating point 0.0 | 0b 00 00 00 00 00 00 00 00 |
Double precision floating point (1.0 / 3.0) | 0b 55 55 55 55 55 55 d5 3f |
Double precision floating point 17.9 | 0b 66 66 66 66 66 e6 31 40 |
Double precision floating point infinity (∞) | 0b 00 00 00 00 00 00 f0 7f |
Double precision floating point negative infinity (-∞) | 0b 00 00 00 00 00 00 f0 ff |
Table 96, “Sample encoding of containers” shows sample encodings for container types. In each of the examples below, the outermost container is encoded as an anonymous element.
Table 96. Sample encoding of containers
Type and Value | Encoding (hex) |
Empty Structure, {} | 15 18 |
Empty Array, [] | 16 18 |
Empty List, [] | 17 18 |
Structure, two context specific tags, Signed Inte ger, 1 octet values, {0 = 42, 1 = -17} | 15 20 00 2a 20 01 ef 18 |
Type and Value | Encoding (hex) | ||||||||||||||
Array, Signed Integer, 1-octet values, [0, 1, 2, 3, 4] |
16 | 00 | 00 | 00 | 01 | 00 | 02 | 00 | 03 | 00 | 04 | 18 | |||
List, mix of anonymous and context tags, Signed Integer, 1 octet values, [[1, 0 = 42, 2, 3, 0 = -17]] |
17 | 00 | 01 | 20 | 00 | 2a | 00 | 02 | 00 | 03 | 20 | 00 | ef | 18 | |
Array, mix of element types, [42, -170000, {}, 17.9, “Hello!”] |
16 0c |
00 06 |
2a 48 |
02 65 |
f0 6c |
67 6c |
fd 6f | ff 21 |
15 18 |
18 | 0a | 33 | 33 | 8f | 41 |
Table 97, “Sample encoding of different tag types” shows sample encoding of a value with different associated tags, using Vendor ID = : 65522 (0xFFF2), one of the Vendor IDs allocated for testing pur poses.
Table 97. Sample encoding of different tag types
Type and Value | Encoding (hex) | ||||||||||||||
Anonymous tag, Unsigned Integer, 1-octet value, 42U |
04 2a | ||||||||||||||
Context tag 1, Unsigned Integer, 1-octet value, 1 = 42U |
24 01 2a | ||||||||||||||
Common profile tag 1, Unsigned Integer, 1-octet value, Matter::1 = 42U | 44 01 00 2a | ||||||||||||||
Common profile tag 100000, Unsigned Integer, 1- octet value, Matter::100000 = 42U | 64 | a0 | 86 | 01 | 00 | 2a | |||||||||
Fully qualified tag, Vendor ID 0xFFF1/65521, pro file number 0xDEED/57069, 2-octet tag 1, Unsigned Integer, 1-octet value 42, 65521::57069:1 = 42U | c4 | f1 | ff | ed | de | 01 | 00 | 2a | |||||||
Fully qualified tag, Vendor ID 0xFFF1/65521, pro file number 0xDEED/57069, 4-octet tag 0xAA55FEED/2857762541, Unsigned Integer, 1-octet value 42, 65521::57069:2857762541 = 42U | e4 | f1 | ff | ed | de | ed | fe | 55 | aa | 2a | |||||
Structure with the fully qualified tag, Vendor ID 0xFFF1/65521, profile number 0xDEED/57069, 2- octet tag 1. The structure contains a single ele ment labeled using a fully qualified tag under the same profile, with 2-octet tag 0xAA55/43605. 65521::57069:1 = {65521::57069:43605 = 42U} |
d5 18 | f1 | ff | ed | de | 01 | 00 | c4 | f1 | ff | ed | de | 55 | aa | 2a |