WARNING ammb-mqtt_handler Invalid MQTT message rejected: Missing 'payload' or 'payload _json' field
Hi,
After receiving an INFO message about the meshtastic name, message fails to send with the above message. I've not yet gotten the bridge to work and am using the most popular observer firmware, already uploading to mqtt using the default topic of meshcore - this publishes to meshcore/IATA/deviceid/packets and meshcore/IATA/deviceid/status
I'm using the corescope internal broker, which is wide open (bad idea for production).
If I point to a specific topic like specifying "meshcore/IATA/HEXDEVICEID/packets" I do see the update with: {"type": "meshtastic_message", "sender_meshtastic_id": "!a2eb419c", "portnum": "TEXT_MESSAGE_APP", "payload": "Test 123", "timestamp_rx": 1789273547.0759733, "rx_rssi": -57, "rx_snr": 5.75, "channel_index": 1, "sender_display_name": "Meshtastic Repeater Ownername"}
Based on the config and usage pages, and the sample config file, it seems that the design is to have MT be "internal" which must be serial - fine. Then MC is mqtt. Don't the messages need to be formatted and hashed so that clients will understand them, starting with an observer with mqtt.rx=true (bridging)? I wasn't able to come across a write-up or example case of this working so any context you can give would be really helpful. Thanks!
-pmow
`WARNING ammb-mqtt_handler Invalid MQTT message rejected: Missing 'payload' or 'payload _json' field`
Hi,
After receiving an INFO message about the meshtastic name, message fails to send with the above message. I've not yet gotten the bridge to work and am using the most popular observer [firmware](https://observer.gessaman.com/), already uploading to mqtt using the default topic of meshcore - this publishes to meshcore/IATA/deviceid/packets and meshcore/IATA/deviceid/status
I'm using the corescope internal broker, which is wide open (bad idea for production).
If I point to a specific topic like specifying "meshcore/IATA/HEXDEVICEID/packets" I do see the update with:
`{"type": "meshtastic_message", "sender_meshtastic_id": "!a2eb419c", "portnum": "TEXT_MESSAGE_APP", "payload": "Test 123", "timestamp_rx": 1789273547.0759733, "rx_rssi": -57, "rx_snr": 5.75, "channel_index": 1, "sender_display_name": "Meshtastic Repeater Ownername"}`
Meshcore sends:
`{"timestamp":"2026-09-13T04:29:52.407921+00:00","hash":"1D342605534E2CB3","origin":"Meshcore Repeater obs","type":"PACKET","direction":"rx","time":"04:29:52","date":"13/09/2026","len":"39","packet_type":"5","route":"F","payload_len":"35","raw":"1502DCD189D184C69F37468FB3E0474C81B3D966D7116D1DFC472C43DB1084FED4CD7732D750AD","origin_id":"4FEF19D131C41F5C936B7E59D93A8D4DA061B1DA2B413D381FC84A20FBCB8E62","SNR":"1.8","RSSI":"-112","score":"784"}`
Based on the config and usage pages, and the sample config file, it seems that the design is to have MT be "internal" which must be serial - fine. Then MC is mqtt. Don't the messages need to be formatted and hashed so that clients will understand them, starting with an observer with mqtt.rx=true (bridging)? I wasn't able to come across a write-up or example case of this working so any context you can give would be really helpful. Thanks!
-pmow
<!-- github-sync-id:5438037516 -->
This is a real protocol mismatch, not a bad config.
AMMB MQTT originally expected its own JSON (destination_meshtastic_id + payload / payload_json). Observer firmware publishes LetsMesh PACKET JSON instead (type=PACKET, raw hex, packet_type, hash). That is why you see Missing 'payload' or 'payload_json' field after the Meshtastic name INFO: the Meshtastic side published fine, then the next MQTT message from the observer failed validation.
If the group channel is not Public, add MESHCORE_CHANNEL_KEY (16-byte hex) or MESHCORE_CHANNEL_KEYS = #room.
mqtt.rx=true on the observer uplinks RF to MQTT. It does not TX AMMB JSON onto LoRa. For Meshtastic → MeshCore RF you still want serial companion_radio, unless your firmware injects observer PACKET JSON onto the radio.
The packet you pasted (packet_type 5, raw starting 1502DC...) is flood GRP_TXT. If it does not decrypt, the channel key is not the Public key — set MESHCORE_CHANNEL_KEY for that room.
This is a real protocol mismatch, not a bad config.
AMMB MQTT originally expected its own JSON (`destination_meshtastic_id` + `payload` / `payload_json`). Observer firmware publishes LetsMesh PACKET JSON instead (`type=PACKET`, `raw` hex, `packet_type`, `hash`). That is why you see `Missing 'payload' or 'payload_json' field` after the Meshtastic name INFO: the Meshtastic side published fine, then the next MQTT message from the observer failed validation.
#16 is addressed in https://github.com/AkitaEngineering/Akita-Meshtastic-Meshcore-Bridge/pull/17
What that change does:
- Accepts observer PACKET JSON on `MQTT_TOPIC_IN` (wildcards like `meshcore/+/+/packets` work).
- Decrypts group text (`packet_type` 5) with the MeshCore Public channel key, plus any extra keys you set.
- Ignores status/neighbors/adverts and encrypted direct messages instead of rejecting them as invalid.
- Optionally publishes Meshtastic text as hashed observer GRP_TXT packets when `MQTT_PAYLOAD_FORMAT = observer`.
Suggested config for your setup:
```ini
EXTERNAL_TRANSPORT = mqtt
MQTT_BROKER = <corescope broker>
MQTT_TOPIC_IN = meshcore/+/+/packets
MQTT_TOPIC_OUT = meshcore/IATA/ammb_bridge/packets
MQTT_PAYLOAD_FORMAT = observer
MESHCORE_INCLUDE_PUBLIC = True
```
If the group channel is not Public, add `MESHCORE_CHANNEL_KEY` (16-byte hex) or `MESHCORE_CHANNEL_KEYS = #room`.
`mqtt.rx=true` on the observer uplinks RF to MQTT. It does not TX AMMB JSON onto LoRa. For Meshtastic → MeshCore RF you still want serial `companion_radio`, unless your firmware injects observer PACKET JSON onto the radio.
The packet you pasted (`packet_type` 5, `raw` starting `1502DC...`) is flood GRP_TXT. If it does not decrypt, the channel key is not the Public key — set `MESHCORE_CHANNEL_KEY` for that room.
<!-- github-comment-id:5656094786 -->
Thank you, understood. I think what confused me is the MQTT support, but meshtastic appeared to be serial only, RNS doesn't support, so that left MC. I'm happy to provide a companion radio for Tx.
Thank you, understood. I think what confused me is the MQTT support, but meshtastic appeared to be serial only, RNS doesn't support, so that left MC. I'm happy to provide a companion radio for Tx.
<!-- github-comment-id:5687701472 -->
Blocking a user prevents them from interacting with repositories, such as opening or commenting on pull requests or issues. Learn more about blocking a user.
WARNING ammb-mqtt_handler Invalid MQTT message rejected: Missing 'payload' or 'payload _json' fieldHi,
After receiving an INFO message about the meshtastic name, message fails to send with the above message. I've not yet gotten the bridge to work and am using the most popular observer firmware, already uploading to mqtt using the default topic of meshcore - this publishes to meshcore/IATA/deviceid/packets and meshcore/IATA/deviceid/status
I'm using the corescope internal broker, which is wide open (bad idea for production).
If I point to a specific topic like specifying "meshcore/IATA/HEXDEVICEID/packets" I do see the update with:
{"type": "meshtastic_message", "sender_meshtastic_id": "!a2eb419c", "portnum": "TEXT_MESSAGE_APP", "payload": "Test 123", "timestamp_rx": 1789273547.0759733, "rx_rssi": -57, "rx_snr": 5.75, "channel_index": 1, "sender_display_name": "Meshtastic Repeater Ownername"}Meshcore sends:
{"timestamp":"2026-09-13T04:29:52.407921+00:00","hash":"1D342605534E2CB3","origin":"Meshcore Repeater obs","type":"PACKET","direction":"rx","time":"04:29:52","date":"13/09/2026","len":"39","packet_type":"5","route":"F","payload_len":"35","raw":"1502DCD189D184C69F37468FB3E0474C81B3D966D7116D1DFC472C43DB1084FED4CD7732D750AD","origin_id":"4FEF19D131C41F5C936B7E59D93A8D4DA061B1DA2B413D381FC84A20FBCB8E62","SNR":"1.8","RSSI":"-112","score":"784"}Based on the config and usage pages, and the sample config file, it seems that the design is to have MT be "internal" which must be serial - fine. Then MC is mqtt. Don't the messages need to be formatted and hashed so that clients will understand them, starting with an observer with mqtt.rx=true (bridging)? I wasn't able to come across a write-up or example case of this working so any context you can give would be really helpful. Thanks!
-pmow
This is a real protocol mismatch, not a bad config.
AMMB MQTT originally expected its own JSON (
destination_meshtastic_id+payload/payload_json). Observer firmware publishes LetsMesh PACKET JSON instead (type=PACKET,rawhex,packet_type,hash). That is why you seeMissing 'payload' or 'payload_json' fieldafter the Meshtastic name INFO: the Meshtastic side published fine, then the next MQTT message from the observer failed validation.#16 is addressed in https://github.com/AkitaEngineering/Akita-Meshtastic-Meshcore-Bridge/pull/17
What that change does:
MQTT_TOPIC_IN(wildcards likemeshcore/+/+/packetswork).packet_type5) with the MeshCore Public channel key, plus any extra keys you set.MQTT_PAYLOAD_FORMAT = observer.Suggested config for your setup:
If the group channel is not Public, add
MESHCORE_CHANNEL_KEY(16-byte hex) orMESHCORE_CHANNEL_KEYS = #room.mqtt.rx=trueon the observer uplinks RF to MQTT. It does not TX AMMB JSON onto LoRa. For Meshtastic → MeshCore RF you still want serialcompanion_radio, unless your firmware injects observer PACKET JSON onto the radio.The packet you pasted (
packet_type5,rawstarting1502DC...) is flood GRP_TXT. If it does not decrypt, the channel key is not the Public key — setMESHCORE_CHANNEL_KEYfor that room.Thank you, understood. I think what confused me is the MQTT support, but meshtastic appeared to be serial only, RNS doesn't support, so that left MC. I'm happy to provide a companion radio for Tx.