OtaSoftwareUpdateProvider Cluster
Cluster ID: 0x0029 |
Endpoint: Fixed on Endpoint 0 (Root Endpoint) |
Role: Client Cluster (implemented by the Provider node)
OtaSoftwareUpdateProvider is the server-side Cluster of the Matter OTA (Over-The-Air) firmware update mechanism — it runs on the node that provides firmware images (typically a Hub, gateway, or cloud proxy), and is responsible for responding to firmware query requests from other devices, controlling update pacing, and receiving update completion notifications.
In Matter's OTA architecture, the device that needs an update is called the Requestor, and the node that provides firmware is called the Provider. The Requestor proactively queries the Provider, which tells it whether a new version is available, where to download it, and whether user consent is required. The entire flow uses a "pull" model, not push.
OtaSoftwareUpdateProvider is a Client Cluster — it defines the commands received by the Provider, not exposed attributes. Therefore, this Cluster has no readable attributes, and all interactions are done through commands. Its counterpart, OtaSoftwareUpdateRequestor (0x002A), is a Server Cluster that runs on the device needing an update, responsible for initiating queries and performing downloads.
Commands
The OtaSoftwareUpdateProvider Cluster has 3 request commands, of which 2 have corresponding response commands and 1 is a one-way notification. These three commands form the complete OTA update lifecycle: Query → Confirm installation → Notify completion. Click on a command ID in the table below to jump to its detailed description.
Requestor → Provider (Request Commands)
| ID | Name | Description | Response |
|---|---|---|---|
0x00 |
QueryImage | Query whether a firmware update is available | QueryImageResponse |
0x02 |
ApplyUpdateRequest | Download complete, request confirmation to install | ApplyUpdateResponse |
0x04 |
NotifyUpdateApplied | Notify Provider that the update has been successfully installed | No response |
Provider → Requestor (Response Commands)
| ID | Name | Description | Corresponding Request |
|---|---|---|---|
0x01 |
QueryImageResponse | Returns firmware query results (update availability, download address, etc.) | QueryImage |
0x03 |
ApplyUpdateResponse | Returns whether the update installation is allowed | ApplyUpdateRequest |
QueryImage — Query Firmware Update (0x00)
The Requestor sends this command to ask the Provider: "I'm a device of this model and version — do you have an update for me?" This is the first step of the entire OTA flow. The Provider determines whether there is an applicable firmware image based on the Requestor's vendor ID, product ID, current version number, and other information.
| Parameter | Type | Required | Description |
|---|---|---|---|
| VendorID | vendor-id | Yes | Requestor's vendor ID (consistent with the one in BasicInformation Cluster) |
| ProductID | uint16 | Yes | Requestor's product ID |
| SoftwareVersion | uint32 | Yes | Requestor's currently running firmware version number |
| ProtocolsSupported | list<DownloadProtocolEnum> | Yes | List of download protocols supported by the Requestor (e.g., BDX, HTTPS) |
| HardwareVersion | uint16 | No | Requestor's hardware version number (some firmware only applies to specific hardware versions) |
| Location | String (2 chars) | No | ISO 3166-1 alpha-2 country code (e.g., "CN"), used for region-restricted firmware distribution |
| RequestorCanConsent | bool | No | Whether the Requestor can display an update consent dialog to the user (e.g., devices with a screen) |
| MetadataForProvider | octstr | No | Vendor-specific metadata (Provider can use this for additional decisions) |
QueryImageResponse Response Fields
| Field | Type | Condition | Description |
|---|---|---|---|
| Status | StatusEnum | Always | Query result status |
| DelayedActionTime | uint32 (seconds) | Optional | When Status is Busy, suggests the Requestor wait this many seconds before retrying |
| ImageURI | String (max 256) | UpdateAvailable | Download address for the firmware image (BDX URI or HTTPS URL) |
| SoftwareVersion | uint32 | UpdateAvailable | Version number of the new firmware |
| SoftwareVersionString | String (max 64) | UpdateAvailable | Version string of the new firmware (human-readable, e.g., "2.0.0") |
| UpdateToken | octstr (max 32) | UpdateAvailable | Update token — subsequent ApplyUpdateRequest and NotifyUpdateApplied must carry this token |
| UserConsentNeeded | bool | Optional | Whether the user needs to manually confirm the update on the Requestor side (default: false) |
| MetadataForRequestor | octstr | Optional | Vendor-specific data returned by the Provider to the Requestor |
UpdateToken is the credential that spans the entire OTA flow. The Requestor must carry the same Token in subsequent ApplyUpdateRequest
and NotifyUpdateApplied calls, allowing the Provider to track the update session.
The Token is at most 32 bytes, generated by the Provider, with content and format defined by the vendor.
Usage Scenarios & Notes
The Requestor typically calls QueryImage at these times: periodic checks (e.g., every 24 hours), after device reboot, or upon receiving an admin's check instruction.
The Provider may return Busy with a DelayedActionTime, telling the Requestor to retry later
— this is common in large device fleets, where the Provider uses staggered scheduling to avoid network congestion from simultaneous downloads.
ApplyUpdateRequest — Request to Install Update (0x02)
After the Requestor downloads and verifies the firmware image, it sends this command to ask the Provider: "I'm ready to install — can I proceed?" The Provider can make a final decision at this point — approve installation, require waiting, or cancel the update. This step gives the Provider ultimate control over the entire update flow.
| Parameter | Type | Description |
|---|---|---|
| UpdateToken | octstr | Update token returned in QueryImageResponse |
| NewVersion | uint32 | Version number of the new firmware to be installed (should match SoftwareVersion in QueryImageResponse) |
ApplyUpdateResponse Response Fields
| Field | Type | Description |
|---|---|---|
| Action | ApplyUpdateActionEnum | Provider's decision on the installation request |
| DelayedActionTime | uint32 (seconds) | When Action is AwaitNextAction, the Requestor should wait this many seconds before requesting again |
Even if the Requestor has already downloaded the firmware, the Provider can still delay installation via AwaitNextAction
(e.g., wait until off-peak hours), or cancel the update entirely via Discontinue (e.g., discovering a critical bug in this version).
This design ensures the Provider maintains control throughout the entire OTA flow.
Usage Scenarios & Notes
Typical flow: Requestor downloads firmware → verifies OTA Image signature → sends ApplyUpdateRequest → receives Proceed → performs installation and reboots. If the Provider returns AwaitNextAction, the Requestor should wait DelayedActionTime seconds before resending ApplyUpdateRequest. If Discontinue is received, the Requestor should abandon installation and discard the downloaded image.
NotifyUpdateApplied — Notify Update Completed (0x04)
After the Requestor successfully installs the firmware and reboots, it sends this command to inform the Provider that the update is complete. This is the last step of the entire OTA flow — a one-way notification with no response command. Upon receipt, the Provider can update its records (e.g., marking the device as updated to the new version).
| Parameter | Type | Description |
|---|---|---|
| UpdateToken | octstr | Token for this update session (same as in QueryImageResponse) |
| SoftwareVersion | uint32 | Current firmware version number after the update |
NotifyUpdateApplied is purely informational — the Requestor does not need confirmation from the Provider. The device has already successfully rebooted and is running the new version; even if the Provider doesn't receive this notification, it doesn't affect the device's normal operation. The Provider typically uses this notification to update statistics (e.g., "how many devices have upgraded to the new version").
Usage Scenarios & Notes
The device should send this notification as soon as possible after reboot. If the Requestor cannot immediately connect to the Provider after reboot (e.g., network recovery takes time), it should send it retroactively once the connection is restored. The specification recommends the Requestor send NotifyUpdateApplied during its first Idle state after reboot.
Enum Definitions
StatusEnum (Query Result Status)
The Status field of QueryImageResponse uses this enum to indicate the Provider's answer to the firmware query.
UpdateAvailable → Start downloading the firmware from ImageURI; Busy → Wait DelayedActionTime seconds then re-send QueryImage; NotAvailable → Nothing to do, check again at the next regular interval; DownloadProtocolNotSupported → Check the Requestor's ProtocolsSupported list to confirm whether a protocol supported by the Provider was missed.
ApplyUpdateActionEnum (Installation Decision)
The Action field of ApplyUpdateResponse uses this enum to indicate the Provider's decision on the installation request.
DownloadProtocolEnum (Download Protocol)
The ProtocolsSupported parameter of QueryImage uses this enum to declare which firmware download methods the Requestor supports.
Most Matter devices use the BDX (Bulk Data Exchange) protocol to download firmware, because it uses the Matter message channel and doesn't require the device to have independent internet connectivity. HTTPS is suitable for Wi-Fi-enabled devices to download directly from the cloud — faster, but requires the device to access the internet. Thread devices (such as door locks and sensors) typically only support BDX, as they connect via Border Routers and may not be able to initiate HTTPS requests directly.
Example Data
QueryImage Interaction Example
The Requestor queries the Provider for available updates — the Provider replies "new version available":
// Requestor → Provider: Query for available firmware
{
"invokeRequests": [{
"commandPath": {
"endpointId": 0,
"clusterId": "0x0029",
"commandId": "0x00" // QueryImage
},
"commandFields": {
"vendorID": 65521, // Vendor ID (0xFFF1 = test vendor)
"productID": 32769, // Product ID
"softwareVersion": 1, // Current firmware version number
"protocolsSupported": [0], // Supported download protocols: BDXSynchronous
"hardwareVersion": 0, // Optional: hardware version
"location": "CN", // Optional: ISO 3166-1 country code
"requestorCanConsent": true, // Optional: whether Requestor can show consent dialog to user
"metadataForProvider": null // Optional: vendor-specific data
}
}]
}
// Provider → Requestor: Update available
{
"status": 0, // UpdateAvailable
"delayedActionTime": 0, // No waiting needed, download immediately
"imageURI": "bdx://provider-node-id/firmware-v2.ota",
"softwareVersion": 2, // New firmware version number
"softwareVersionString": "2.0.0",
"updateToken": "dXBkYXRlLXRva2VuLXYy", // Base64-encoded update token
"userConsentNeeded": false, // No additional user confirmation needed
"metadataForRequestor": null // No vendor-specific data
}
ApplyUpdateRequest Interaction Example
The Requestor has finished downloading and asks the Provider to confirm whether installation can proceed:
// Requestor → Provider: Download complete, requesting to apply update
{
"invokeRequests": [{
"commandPath": {
"endpointId": 0,
"clusterId": "0x0029",
"commandId": "0x02" // ApplyUpdateRequest
},
"commandFields": {
"updateToken": "dXBkYXRlLXRva2VuLXYy", // Token from QueryImageResponse
"newVersion": 2 // Version number to be installed
}
}]
}
// Provider → Requestor: Confirm installation
{
"action": 0, // Proceed (allow installation)
"delayedActionTime": 0 // No waiting needed
}
NotifyUpdateApplied Example
After the Requestor successfully installs and reboots, it notifies the Provider that the update is complete:
// Requestor → Provider: Successfully installed and rebooted
{
"invokeRequests": [{
"commandPath": {
"endpointId": 0,
"clusterId": "0x0029",
"commandId": "0x04" // NotifyUpdateApplied
},
"commandFields": {
"updateToken": "dXBkYXRlLXRva2VuLXYy", // Original update token
"softwareVersion": 2 // Current version number after update
}
}]
}
// This command has no response (one-way notification)
When developing an OTA Provider, the core logic lies in handling QueryImage — you need to match the correct firmware based on VendorID + ProductID + SoftwareVersion,
and select the appropriate download method via ProtocolsSupported.
If you have a large device fleet, make good use of the Busy status and DelayedActionTime for staggered distribution.
Common Scenarios
Scenario 1: Standard Firmware Update Flow
- Requestor sends
QueryImage (0x00)to Provider, carrying its own vendor ID, product ID, current version number, and supported download protocols - Provider replies with
QueryImageResponse, Status =UpdateAvailable, including ImageURI, new version number, and UpdateToken - Requestor downloads the firmware image via ImageURI (BDX or HTTPS)
- After download completes, Requestor verifies the image signature (OTA Image header contains vendor signature)
- Verification passes, Requestor sends
ApplyUpdateRequest (0x02), carrying UpdateToken and NewVersion - Provider replies with
ApplyUpdateResponse, Action =Proceed - Requestor performs firmware installation and reboots
- After reboot, Requestor sends
NotifyUpdateApplied (0x04)to inform the Provider of the successful update
The entire flow from query to installation completion typically takes several minutes to tens of minutes, depending on firmware size and network conditions.
Scenario 2: Firmware Rollback (Emergency Withdrawal of Problematic Version)
- The vendor discovers a critical bug in v2.0.0 that requires emergency withdrawal
- The Provider removes v2.0.0 firmware and offers v1.0.1 instead (fix version or rollback version)
- Devices already updated to v2.0.0 will receive UpdateAvailable pointing to v1.0.1 on their next QueryImage
- Devices not yet updated will receive
NotAvailableon QueryImage (skipping v2.0.0) - If a device has downloaded v2.0.0 but not yet installed it (at the ApplyUpdateRequest stage), Provider replies
Discontinueto cancel installation
Key point: The Matter OTA specification allows "downgrade" updates — SoftwareVersion can be lower than the current version. However, whether a downgrade actually succeeds depends on the device implementation: some devices' bootloaders may reject installing firmware with a version lower than the current one.
Scenario 3: Multi-Device Batch Update (Staggered Distribution)
- The vendor releases new firmware, with 10,000 devices in the fleet needing updates
- The Provider doesn't want all devices downloading simultaneously to avoid network congestion
- The first 100 devices querying via QueryImage receive
UpdateAvailable, allowed to download immediately - Starting from device 101, the Provider replies
Busywith DelayedActionTime = 3600 (retry in 1 hour) - After each batch completes, the Provider gradually opens up the next batch's quota
- If the Provider wants a device to wait until off-peak hours after downloading, ApplyUpdateRequest replies
AwaitNextActionwith DelayedActionTime set to the seconds until the desired time
Implementation suggestion: The Provider can maintain an update queue and concurrency counter.
By flexibly using Busy (controlling download concurrency) and AwaitNextAction (controlling installation timing),
you can achieve smooth canary releases and staggered distribution.
Scenario 4: Update Requiring User Consent
- Requestor declares
RequestorCanConsent = truein QueryImage (the device has a screen and can display a confirmation dialog) - Provider replies with UpdateAvailable,
UserConsentNeeded = true - Upon receiving the response, the Requestor displays a confirmation dialog on the device screen: "New version v2.0.0 is available. Do you want to update?"
- Only after the user clicks "Confirm" does the Requestor start downloading the firmware
- If the user declines, the Requestor does not download and asks again at the next check interval
Screenless devices: If the Requestor has no screen (RequestorCanConsent = false),
the Provider typically won't set UserConsentNeeded = true. For such devices, user consent can be obtained through
the OTA management interface in a mobile app (the app acts as an intermediary conveying the user's intent).