Descriptor Cluster
Cluster ID: 0x001D |
Endpoint: Every Endpoint must have it (including Endpoint 0)
Descriptor is the most fundamental Cluster in the Matter protocol. It answers one core question: What is on this Endpoint? When a Controller (phone, smart speaker, hub) connects to a Matter device, the first thing it does is read the Descriptor on each Endpoint to learn which Device Types the device supports, which Clusters are implemented, and the hierarchical relationship between Endpoints.
This Cluster is entirely read-only — it has no Commands, only Attributes. The information is determined at manufacturing time and does not change at runtime.
The Descriptor Cluster is a mandatory requirement in the Matter specification. Whether it is Endpoint 0 (Root Node) or an application Endpoint (Endpoint 1, 2, 3...), every Endpoint must include the Descriptor Cluster. If your device is missing it, it will not pass Matter certification, and Controllers will be unable to correctly identify the device's capabilities.
What Problem Does Descriptor Solve
The data model of a Matter device is a tree structure: a Node (physical device) contains multiple Endpoints, and each Endpoint represents a functional unit. However, when a Controller connects to a device, it does not know what this tree looks like. Descriptor is the self-describing mechanism of this tree:
- DeviceTypeList — Tells the Controller "what I am" (door lock? light? switch?)
- ServerList / ClientList — Tells the Controller "what I can do" (which Clusters are supported)
- PartsList — Tells the Controller "what is under me" (list of child Endpoints)
Endpoint 0 is the Root Node, and its Descriptor has special significance:
- Its
PartsListenumerates all other Endpoint numbers on the device and serves as the entry point for device discovery - The standard Controller flow is: first read Endpoint 0's PartsList to get all Endpoint numbers, then read each Endpoint's Descriptor individually
- The Root Node's DeviceType is
0x0016(Root Node Device Type)
Attribute Overview
Descriptor has only 5 attributes, but each one is essential. Click an attribute ID to jump to its detailed description.
| ID | Name | Type | Required | Description |
|---|---|---|---|---|
0x0000 |
DeviceTypeList | list<DeviceTypeStruct> | Yes | List of Device Types supported by the Endpoint |
0x0001 |
ServerList | list<cluster_id> | Yes | List of Server Clusters implemented by the Endpoint |
0x0002 |
ClientList | list<cluster_id> | Yes | List of Client Clusters implemented by the Endpoint |
0x0003 |
PartsList | list<endpoint_id> | Yes | List of child Endpoint numbers |
0x0004 |
TagList | list<SemanticTagStruct> | No | Semantic tag list (used to distinguish similar Endpoints) |
Attributes
DeviceTypeList (0x0000)
Lists all Device Types supported by this Endpoint. Each entry is a DeviceTypeStruct containing the Device Type ID and revision number.
Most Endpoints have only one Device Type, but the specification allows an Endpoint to declare multiple.
DeviceTypeStruct Structure
| Field | Type | Description |
|---|---|---|
| DeviceType | devtype_id (uint32) | Device Type ID, e.g. 0x000A = Door Lock, 0x0100 = On/Off Light |
| Revision | uint16 | The revision number of this Device Type definition, used to distinguish differences between specification versions |
0x0016 Root Node |
0x000A Door Lock |
0x0100 On/Off Light |
0x010D Extended Color Light |
0x000E Aggregator (Bridge) |
0x0107 Dimmable Light
ServerList (0x0001)
Lists all Cluster IDs that this Endpoint implements as a Server.
A Server is the side that holds data and responds to read/write requests.
For example, the ServerList of a door lock's Endpoint 1 would include 0x0101 (DoorLock),
because the lock's state (locked/unlocked, user list, etc.) is stored on the device.
By reading the ServerList, a Controller knows which Clusters it can send read/write/command requests to on this Endpoint.
ClientList (0x0002)
Lists all Cluster IDs that this Endpoint implements as a Client. A Client is the side that initiates requests — most end devices (lights, locks, sensors) have an empty ClientList because they are only controlled and do not actively control other devices.
A typical scenario where ClientList is non-empty: a physical switch.
A wall switch declares 0x0006 (OnOff Client) in its ClientList,
indicating that it will actively send on/off commands to lights.
PartsList (0x0003)
Lists the child Endpoint numbers of this Endpoint. This attribute defines the hierarchical relationship between Endpoints.
On Endpoint 0 (Root Node):
- PartsList is a flat list containing the numbers of all other Endpoints on the Node
- This is the sole entry point for a Controller to discover all application Endpoints on the device
- Example:
[1, 2, 3]means the device has 3 additional application Endpoints
On application Endpoints (Endpoint 1, 2, 3...):
- In most cases it is an empty list (leaf Endpoint with no children)
- Only Bridge / Aggregator device Endpoints have a non-empty PartsList, pointing to their bridged child device Endpoints
TagList (0x0004) — Optional
Attaches semantic tags to the Endpoint, used to distinguish Endpoints that have the same function but different locations or purposes. For example, a device with two temperature sensor Endpoints can use TagList to label one as "Indoor" and the other as "Outdoor".
TagList requires the device to declare the TAGLIST Feature (Feature Bit 0) in order to be present.
SemanticTagStruct Structure
| Field | Type | Description |
|---|---|---|
| MfgCode | vendor_id (nullable) | Vendor code. null means a standard-defined tag; non-null indicates a vendor-specific custom tag |
| NamespaceID | uint8 | Tag namespace ID, defining the tag classification system |
| Tag | uint8 | Tag value, with specific meaning within the corresponding namespace |
| Label | string (nullable) | Optional human-readable tag text, e.g. "Indoor", "Left" |
How Controllers Use Descriptor to Discover Devices
After connecting to a Matter device, the Controller follows this standard Endpoint discovery flow:
- Read Endpoint 0's PartsList — Get all application Endpoint numbers, e.g.
[1, 2, 3] - Iterate over each Endpoint and read DeviceTypeList — Learn that Endpoint 1 is a door lock, Endpoint 2 is a temperature sensor, etc.
- Read ServerList — Learn which specific Clusters each Endpoint supports (what operations are available)
- Build the UI based on this information — Show an unlock button for the door lock Endpoint, display a temperature reading for the sensor Endpoint
In practice, Controllers typically do not read attributes one by one. Instead, they use a Wildcard Read to fetch the Descriptor Cluster from all Endpoints in a single request, which is much more efficient. However, understanding the step-by-step flow above helps clarify the role of each Descriptor attribute.
Open the JSON Parser, pick the "Raw device data" sample and click Parse to see a door lock's DeviceTypeList, ServerList and PartsList translated into device types and cluster names.
The numbers in DeviceTypeList (e.g. 10 = 0x000A Door Lock) can be looked up in the Matter ID Lookup.
Example Data
Scenario 1: Standard Device (Door Lock)
Descriptor of Endpoint 0 (Root Node):
{
// Descriptor of Endpoint 0 (Root Node)
"DeviceTypeList": [
{ "DeviceType": "0x0016", "Revision": 2 } // Root Node
],
"ServerList": [
"0x001D", // Descriptor
"0x0028", // BasicInformation
"0x002F", // PowerSource
"0x0030", // GeneralCommissioning
"0x0031", // NetworkCommissioning
"0x003E", // OperationalCredentials
"0x0033" // GeneralDiagnostics
],
"ClientList": [],
"PartsList": [ 1, 2, 3 ] // This Node also has Endpoints 1, 2, 3
}
Descriptor of Endpoint 1 (door lock application Endpoint):
{
// Descriptor of Endpoint 1 (application Endpoint, e.g. a door lock)
"DeviceTypeList": [
{ "DeviceType": "0x000A", "Revision": 3 } // DoorLock
],
"ServerList": [
"0x001D", // Descriptor (itself)
"0x0003", // Identify
"0x0101", // DoorLock
"0x002F" // PowerSource
],
"ClientList": [],
"PartsList": [] // Leaf Endpoint, no children
}
Scenario 2: Bridge Device
The PartsList of a Bridge (gateway/aggregator) device's Endpoint 0 lists all bridged child devices:
{
// Descriptor of Endpoint 0 (Bridge device)
"DeviceTypeList": [
{ "DeviceType": "0x000E", "Revision": 2 } // Aggregator (Bridge)
],
"ServerList": [ "0x001D", "0x0028", "0x0039" ],
"PartsList": [ 1, 2, 3, 4, 5 ] // Bridging 5 child devices
// Each child Endpoint (1-5) has its own independent Descriptor,
// describing its own DeviceType and Cluster lists
}
When debugging, if a Controller fails to recognize a device's functionality, check the Descriptor first:
- Does Endpoint 0's PartsList include the application Endpoint in question?
- Is the application Endpoint's DeviceTypeList correct?
- Does the application Endpoint's ServerList include the required Clusters?