invalid payload field #5

Closed
opened 2026-10-05 05:04:02 +02:00 by adam · 2 comments
Owner

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"}

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

`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 -->
adam closed this issue 2026-10-05 05:04:02 +02:00
Author
Owner

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:

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.

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 -->
Author
Owner

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 -->
Sign in to join this conversation.
No labels
1 Participants
Notifications
Due Date
No due date set.
Dependencies

No dependencies set.

Reference: adam/Akita-Meshtastic-Meshcore-Bridge#5