thingsboard / thingsboard/thingsboard
[BUG] MQTT Protobuf field names converted from snake_case to camelCase automatically
@ViacheslavKlimov is already working on this.
Since Jan 5, 2026.
- Dominant language
- Java
- Stars
- 22.4k
- Forks
- 6.5k
- Avg merge
- 18h 26m
- Merged PRs (30d)
- 37
Description
Problem Statement
Protocol Buffer messages sent via MQTT with snake_case field names are being automatically converted to lowerCamelCase when stored in ThingsBoard. This is a breaking change that affects backward compatibility with existing Protobuf-based IoT devices. Above all, it affects to firmware updates because key you can't choose the key that server sends.
Server Environment
- [EU ThingsBoard Cloud] (https://eu.thingsboard.cloud)
Your Client Environment
- Independent
Connectivity
- MQTT with pb
Expected behavior
Protobuf field names should be preserved as defined in the .proto schema:
- Field:
current_fw_title→ stored ascurrent_fw_title - Field:
fw_state→ stored asfw_state - Field:
target_fw_version→ stored astarget_fw_version
Actual behavior
Protobuf field names are converted to lowerCamelCase:
- Field:
current_fw_title→ stored ascurrentFwTitle✗ - Field:
fw_state→ stored asfwState✗ - Field:
target_fw_version→ stored astargetFwVersion✗
Possible cause (My Analysis)
I believe this is caused by Protobuf 3.25.5 (introduced in ThingsBoard v4.2.0) where JsonFormat.printer() converts field names to lowerCamelCase by default:
- ThingsBoard Code: https://github.com/thingsboard/thingsboard/blob/master/pom.xml shows
<protobuf.version>3.25.5</protobuf.version> - Protobuf Spec: https://protobuf.dev/programming-guides/json/ states "In proto3, field names are converted to lowerCamelCase format in JSON output"
- Solution Available: https://cloud.google.com/java/docs/reference/protobuf/latest/com.google.protobuf.util.JsonFormat.Printer has
preservingProtoFieldNames()method but it's not used
Impact
- OTA Firmware Updates: Fields like
current_fw_title,fw_state,target_fw_versiondocumented in ThingsBoard OTA guide are not recognized - Backward Compatibility: Breaking change for existing Protobuf-based devices
- Data Integrity: Duplicate attribute names (camelCase versions contain data, snake_case versions are empty)
- Silent Breaking Change: No migration path or documentation provided when v4.2.0 was released
Steps to reproduce
- Define a Protobuf message with snake_case field names:
message FirmwareStatus { string current_fw_title = 1; string current_fw_version = 2; string fw_state = 3; string target_fw_title = 4; string target_fw_version = 5; } - Send message via MQTT from IoT device
- Check device attributes or telemetry in ThingsBoard
- Expected: Attributes named
current_fw_title,current_fw_version, etc. - Actual: Attributes named
currentFwTitle,currentFwVersion, etc.
Note
I'm reporting this based on the evidence of duplicate telemetry or atributtes (only camelCase versions have data), the version upgrade timeline coinciding with my observation , and the official Protobuf documentation about default camelCase conversion.
However, I'm not 100% certain about the exact implementation details or if there are other factors I'm missing. The main problem is clearly visible (snake_case fields being converted to camelCase), but I could be wrong about the root cause.
If I've misdiagnosed the issue, I apologize and would appreciate any clarification. I'm just trying to report what I'm observing to help improve ThingsBoard!
Thanks for reviewing this! 🙏
Contributor guide
No contributing guide indexed for this repository
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.
Assessment
This issue has not been assessed yet.