{"record":{"id":"3635504f13f040e4","repo":"apache/pulsar","slug":"the-update-payload-operation-only-support-multi-ch","errorCode":null,"errorMessage":"The update payload operation only support multi chunked messages.","messagePattern":"The update payload operation only support multi chunked messages\\.","errorType":"exception","errorClass":"RuntimeException","httpStatus":null,"severity":"error","filePath":"pulsar-common/src/main/java/org/apache/pulsar/common/api/raw/RawMessageImpl.java","lineNumber":88,"sourceCode":"            long ledgerId, long entryId, long batchIndex) {\n        RawMessageImpl msg = RECYCLER.get();\n        msg.msgMetadata = msgMetadata;\n        msg.msgMetadata.retain();\n\n        if (singleMessageMetadata != null) {\n            msg.singleMessageMetadata.copyFrom(singleMessageMetadata);\n            msg.setSingleMessageMetadata = true;\n        }\n        msg.messageId.ledgerId = ledgerId;\n        msg.messageId.entryId = entryId;\n        msg.messageId.batchIndex = batchIndex;\n        msg.payload = payload;\n        return msg;\n    }\n\n    public RawMessage updatePayloadForChunkedMessage(ByteBuf chunkedTotalPayload) {\n        if (!msgMetadata.getMetadata().hasNumChunksFromMsg() || msgMetadata.getMetadata().getNumChunksFromMsg() <= 1) {\n            throw new RuntimeException(\"The update payload operation only support multi chunked messages.\");\n        }\n        payload = chunkedTotalPayload;\n        return this;\n    }\n\n    @Override\n    public Map<String, String> getProperties() {\n        if (setSingleMessageMetadata && singleMessageMetadata.getPropertiesCount() > 0) {\n            return singleMessageMetadata.getPropertiesList().stream()\n                      .collect(Collectors.toMap(KeyValue::getKey, KeyValue::getValue,\n                              (oldValue, newValue) -> newValue));\n        } else if (msgMetadata.getMetadata().getPropertiesCount() > 0) {\n            return msgMetadata.getMetadata().getPropertiesList().stream()\n                    .collect(Collectors.toMap(KeyValue::getKey, KeyValue::getValue,\n                            (oldValue, newValue) -> newValue));\n        } else {\n            return Collections.emptyMap();\n        }","sourceCodeStart":70,"sourceCodeEnd":106,"githubUrl":"https://github.com/apache/pulsar/blob/820761864ed8e2a7d2e52dd9763ad2ae117c1395/pulsar-common/src/main/java/org/apache/pulsar/common/api/raw/RawMessageImpl.java#L70-L106","documentation":"RawMessageImpl.updatePayloadForChunkedMessage reassembles a chunked message by replacing its payload with a merged buffer, but it only works when the message metadata actually records chunk counts (hasNumChunksFromMsg with numChunksFromMsg > 1). For non-chunked or single-chunk messages there is nothing to reassemble, so it throws RuntimeException.","triggerScenarios":"Calling updatePayloadForChunkedMessage on a RawMessage whose metadata lacks numChunksFromMsg or has numChunksFromMsg <= 1 — i.e. the message was not published with chunking enabled or arrived as a single chunk.","commonSituations":"Raw reading consumers that process topics mixing chunked and non-chunked messages; chunking disabled on the producer but the consumer code unconditionally calls the merge path; messages produced by old brokers/clients that don't set numChunksFromMsg metadata.","solutions":["Check metadata before merging: only call updatePayloadForChunkedMessage when hasNumChunksFromMsg() && getNumChunksFromMsg() > 1; otherwise keep the original payload.","Enable message chunking on the producer (setChunkingEnabled / maxMessageSize config) so chunk metadata is present.","Catch RuntimeException and fall back to using the unmodified RawMessage payload for non-chunked messages."],"exampleFix":"// before\nmsg.updatePayloadForChunkedMessage(totalBuffer);\n// after\nif (msg.getMetadata().getMetadata().hasNumChunksFromMsg()\n        && msg.getMetadata().getMetadata().getNumChunksFromMsg() > 1) {\n    msg.updatePayloadForChunkedMessage(totalBuffer);\n} else {\n    // use msg as-is: not a multi-chunk message\n}","handlingStrategy":"validation","validationCode":"boolean isMultiChunk = rawMsg.getMetadata().getMetadata().hasNumChunksFromMsg()\n    && rawMsg.getMetadata().getMetadata().getNumChunksFromMsg() > 1;","typeGuard":null,"tryCatchPattern":"if (isMultiChunk) {\n    msg.updatePayloadForChunkedMessage(totalBuffer);\n} // else: use the message payload as-is","preventionTips":["Always check hasNumChunksFromMsg()/getNumChunksFromMsg() before merging.","Enable chunking on producers that publish messages needing reassembly.","Handle topics that mix chunked and non-chunked messages explicitly."],"tags":["chunking","raw-reader","message-payload","precondition"],"backgroundTag":"message-not-chunked","analyzedSha":"820761864ed8e2a7d2e52dd9763ad2ae117c1395","analyzedAt":"2026-09-06T00:14:20.138Z","contentChangedAt":"2026-09-06T00:14:20.138Z","schemaVersion":2},"datasetVersion":"2026-09-14T05:17:10.506Z"}