Firmware update fails on asset tracking devices due to MQTT payload size limits

We’re experiencing firmware update failures on our fleet of 850+ asset tracking devices. The OTA firmware update process consistently fails when pushing updates larger than 256KB through our MQTT broker.

Error from device logs:


MQTT Publish Failed: Payload Too Large (262144 bytes)
Max allowed: 256000 bytes
Firmware chunk 3/8 rejected

We’ve configured the MQTT broker payload size to 1MB in the SAP IoT Application Enablement settings, but devices still reject larger chunks. The chunked firmware transfer logic seems to work for the first two chunks (128KB each), then fails on subsequent transfers.

Has anyone dealt with MQTT broker payload size configuration issues in SAP IoT 2.5? We need to understand if this is a broker-side limit, device-side buffer constraint, or something in the chunking algorithm.

You can implement device capability negotiation. When a device connects, it publishes its max payload size to a capability topic. Your OTA service reads this and adjusts chunk size accordingly. We built a simple capability registry that maps device IDs to their MQTT constraints. The chunking service queries this before starting any firmware push. It’s an extra step but works well for mixed device fleets with varying capabilities.

Let me provide a comprehensive solution addressing all three aspects of your issue:

1. MQTT Broker Payload Size Configuration The broker-side 1MB limit you set is correct, but you need to verify it’s actually applied. Check the MQTT broker logs (typically in SAP IoT Data Services) to confirm the maxPayloadSize parameter is active. Also ensure your MQTT topic permissions allow large payloads - some default security policies restrict payload sizes regardless of broker settings.

2. OTA Firmware Update Process Implement a two-phase approach:

  • Phase 1: Device handshake - device publishes its capabilities including max MQTT payload size
  • Phase 2: Adaptive chunking - OTA service calculates optimal chunk size as min(device_max_payload - 16KB overhead, 240KB safe_limit)

The 16KB overhead accounts for MQTT headers, JSON wrapping, and base64 encoding if you’re using it.

3. Chunked Firmware Transfer Logic Here’s the key fix - modify your chunking algorithm:

// Calculate safe chunk size per device
const deviceMaxPayload = deviceProfile.mqttMaxPayload || 256000;
const safeChunkSize = Math.min(deviceMaxPayload - 16384, 240000);
const totalChunks = Math.ceil(firmwareSize / safeChunkSize);

In your SAP IoT Application Enablement custom service, you’ll need to:

  1. Create a device capability table in IoT Data Storage Module to persist MQTT constraints per device
  2. Modify the firmware update service to query this table before starting transfers
  3. Implement retry logic with exponentially decreasing chunk sizes (240KB → 128KB → 64KB) if transfers still fail

Implementation Steps:

First, enhance your device registration to capture MQTT capabilities. When devices connect, have them publish to devices/{deviceId}/capabilities:

{
  "mqttMaxPayload": 256000,
  "firmwareVersion": "1.2.3",
  "availableMemory": 512000
}

Then update your OTA service’s chunking logic to respect these limits. The service should fetch device capabilities before calculating chunks and adjust accordingly.

For your immediate issue: Since you can’t reflash all devices now, configure your OTA service to use a conservative 220KB chunk size globally. This leaves enough headroom for all devices with 256KB limits. You can optimize this later as you upgrade device firmware to support larger payloads.

Also check your SAP IoT Edge Gateway configuration if you’re routing through gateways - they have their own payload limits that can create bottlenecks even if broker and devices support larger sizes.

This approach has worked for several deployments I’ve supported with mixed device capabilities ranging from 128KB to 1MB MQTT payload support.

Also worth checking the chunk size calculation in your OTA update service. If you’re dynamically calculating chunk sizes based on available memory, the algorithm might not account for MQTT protocol overhead (headers, QoS flags, etc.). Try reducing your chunk size to 240KB to leave headroom for protocol data. We had similar issues and switching from fixed 256KB chunks to adaptive 220-240KB chunks solved it.

Another option is to use SAP IoT’s built-in device profiles feature. You can define a device profile with MQTT payload constraints, then assign devices to profiles based on their hardware capabilities. The firmware update service in Application Enablement 2.5 can read these profiles and auto-adjust chunking. It’s cleaner than custom capability negotiation and integrates with the existing device management workflow.