Inverted logic for ZCL frame type handling in ZCL default response
Nobody has claimed this yet.
- Dominant language
- TypeScript
- Stars
- 15.7k
- Forks
- 2k
- Avg merge
- 18h 55m
- Merged PRs (30d)
- 35
Description
What happened?
I implement a custom Zigbee stack (it will be open-sourced soon once usable). I mostly test it with Z2M. During the testing I found this issue.
My sample device has a ZHA On/Off cluster input. For now I reply with a default response with "Unsupported Cluster Command" status. And here is the problem – when I accidentally set ZCL frame type to be "Cluster-specific", Z2M properly reacts to these responses, logging these messages:
[7/15/2026, 11:05:59 AM] frontend:api: Sending {"topic":"0xc001babedeadbeef/set","payload":{"state":"OFF"}}
[7/15/2026, 11:05:59 AM] z2m: Publish 'set' 'state' to '0xc001babedeadbeef' failed: 'Error: ZCL command 0xc001babedeadbeef/1 genOnOff.off({}, {"timeout":10000,"disableResponse":false,"disableRecovery":false,"disableDefaultResponse":false,"direction":0,"reservedBits":0,"writeUndiv":false}) failed (Status 'UNSUP_COMMAND' response genOnOff:11)'
[7/15/2026, 11:06:00 AM] frontend:api: Sending {"topic":"0xc001babedeadbeef/set","payload":{"state":"ON"}}
[7/15/2026, 11:06:00 AM] z2m: Publish 'set' 'state' to '0xc001babedeadbeef' failed: 'Error: ZCL command 0xc001babedeadbeef/1 genOnOff.on({}, {"timeout":10000,"disableResponse":false,"disableRecovery":false,"disableDefaultResponse":false,"direction":0,"reservedBits":0,"writeUndiv":false}) failed (Status 'UNSUP_COMMAND' response genOnOff:11)'
ZigBee Cluster Library Frame
Frame Control Field: Cluster-specific (0x19)
.... ..01 = Frame Type: Cluster-specific (0x1)
.... .0.. = Manufacturer Specific: False
.... 1... = Direction: Server to Client
...1 .... = Disable Default Response: True
Sequence Number: 157
When I fix the default response frame to be properly set to "Profile wide" since "Default response" is not a cluster-specific command, Z2M no longer displays these errors:
[7/15/2026, 10:59:49 AM] z2m:mqtt: MQTT publish: topic 'zigbee2mqtt/0xc001babedeadbeef', payload '{"linkquality":45,"state":"ON"}'
[7/15/2026, 10:59:54 AM] z2m:mqtt: MQTT publish: topic 'zigbee2mqtt/0xc001babedeadbeef', payload '{"linkquality":60,"state":"OFF"}'
Howerver Wireshark now can properly decode the default responses:
ZigBee Cluster Library Frame, Command: Default Response, Seq: 1
Frame Control Field: Profile-wide (0x18)
.... ..00 = Frame Type: Profile-wide (0x0)
.... .0.. = Manufacturer Specific: False
.... 1... = Direction: Server to Client
...1 .... = Disable Default Response: True
Sequence Number: 1
Command: Default Response (0x0b)
Response to Command: 0x00
Status: Unsupported Cluster Command (0x81)
So it seems there is a problem in Z2M, it parses default responses when it should not and vice versa. I think it's worth checking it. It may cause other problems as well.
Z2M: 2.12.1 aa909a8a
zigbee-herdsman-converters version 26.76.0
zigbee-herdsman version 10.6.1
Coordinator ZStack3x0 0x00124b0022988ab4 Revision: 20210120
What did you expect to happen?
No response
How to reproduce it (minimal and precise)
No response
Zigbee2MQTT version
2.12.1
Adapter firmware version
20210120
Adapter
Electrolama
Setup
Plain
Device database.db entry
No response
Debug log
No response
Notes
No response
Contributor guide
First steps
- Read the whole issue, then the project's contributing guide.
- Comment on the issue to say you are picking it up — it saves two people doing the same work.
- Fork the repository and make your change on a branch.
- Open a pull request that references the issue number.
Research direction
The issue does not name implementation files or tests. Start by locating the Zigbee ZCL default-response parsing path and compare handling of profile-wide versus cluster-specific frame types using the supplied captures; done means responses are accepted or ignored according to their frame type and regression coverage verifies both cases.
Written by the indexing model from the issue text.
Assessment
- Tech stack
- typescript
- Domain
- embedded-iot, networking
- Issue type
- Bug
- Difficulty
- 4/5
- Estimated time
- 3-5 days
- Activity status
- Active
- Clarity
- Mostly clear
- Newbie friendliness
- 45/100