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.

Mandatory: Every Endpoint Must Implement Descriptor

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)
The Special Role of Endpoint 0

Endpoint 0 is the Root Node, and its Descriptor has special significance:

  • Its PartsList enumerates 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
Common Device Type IDs

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.

Two Usages of PartsList

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:

  1. Read Endpoint 0's PartsList — Get all application Endpoint numbers, e.g. [1, 2, 3]
  2. Iterate over each Endpoint and read DeviceTypeList — Learn that Endpoint 1 is a door lock, Endpoint 2 is a temperature sensor, etc.
  3. Read ServerList — Learn which specific Clusters each Endpoint supports (what operations are available)
  4. Build the UI based on this information — Show an unlock button for the door lock Endpoint, display a temperature reading for the sensor Endpoint
The Wildcard Read Alternative

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.

Try it: read device types from raw data

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
}
Developer Tip

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?