{"record":{"id":"6451bb6695fb43ba","repo":"alibaba/spring-cloud-alibaba","slug":"defaultmqpushconsumer-consuming-failed-caused-by","errorCode":null,"errorMessage":"DefaultMQPushConsumer consuming failed, Caused by messageExtList is empty","messagePattern":"DefaultMQPushConsumer consuming failed, Caused by messageExtList is empty","errorType":"exception","errorClass":"MessagingException","httpStatus":null,"severity":"warning","filePath":"spring-cloud-alibaba-starters/spring-cloud-starter-stream-rocketmq/src/main/java/com/alibaba/cloud/stream/binder/rocketmq/integration/inbound/RocketMQInboundChannelAdapter.java","lineNumber":137,"sourceCode":"\t\t\t\t\t\"DefaultMQPushConsumer init failed, Caused by \" + e.getMessage())\n\t\t\t\t\t.build(), e);\n\t\t}\n\t}\n\n\t/**\n\t * The actual execution of a user-defined input consumption service method.\n\t * @param messageExtList rocket mq message list\n\t * @param failSupplier {@link ConsumeConcurrentlyStatus} or\n\t *     {@link ConsumeOrderlyStatus}\n\t * @param sucSupplier {@link ConsumeConcurrentlyStatus} or\n\t *     {@link ConsumeOrderlyStatus}\n\t * @param <R> object\n\t * @return R\n\t */\n\tprivate <R> R consumeMessage(List<MessageExt> messageExtList,\n\t\t\tSupplier<R> failSupplier, Supplier<R> sucSupplier) {\n\t\tif (CollectionUtils.isEmpty(messageExtList)) {\n\t\t\tthrow new MessagingException(\n\t\t\t\t\t\"DefaultMQPushConsumer consuming failed, Caused by messageExtList is empty\");\n\t\t}\n\t\t// With consumeMessageBatchMaxSize > 1, a recoveryCallback that throws midway\n\t\t// through a batch causes the whole batch to be redelivered, so previously\n\t\t// recovered messages will be recovered again. Prefer batchSize=1 when relying\n\t\t// on recoveryCallback for DLQ wiring.\n\t\tfor (MessageExt messageExt : messageExtList) {\n\t\t\ttry {\n\t\t\t\tMessage<?> message = RocketMQMessageConverterSupport\n\t\t\t\t\t\t.convertMessage2Spring(messageExt);\n\t\t\t\tif (this.retryTemplate != null) {\n\t\t\t\t\ttry {\n\t\t\t\t\t\tthis.retryTemplate.execute(() -> {\n\t\t\t\t\t\t\tthis.sendMessage(message);\n\t\t\t\t\t\t\treturn Boolean.TRUE;\n\t\t\t\t\t\t});\n\t\t\t\t\t}\n\t\t\t\t\tcatch (RetryException retryException) {","sourceCodeStart":119,"sourceCodeEnd":155,"githubUrl":"https://github.com/alibaba/spring-cloud-alibaba/blob/115d5901102009492e05d5ec18c3f79cad4077d0/spring-cloud-alibaba-starters/spring-cloud-starter-stream-rocketmq/src/main/java/com/alibaba/cloud/stream/binder/rocketmq/integration/inbound/RocketMQInboundChannelAdapter.java#L119-L155","documentation":"A defensive guard in consumeMessage: RocketMQ delivered an empty message batch, which the adapter cannot iterate. Rather than silently no-op, it throws MessagingException. In practice this indicates a client-side or batching anomaly rather than a normal empty-poll (the pull consumer returns null instead).","triggerScenarios":"The push MessageListener/consume path calls consumeMessage with an empty or null `messageExtList`.","commonSituations":"Misconfigured `consumeMessageBatchMaxSize`; a custom listener that manually forwards an empty list; broker/client version mismatch producing zero-length batches; the recoveryCallback path mishandling batches.","solutions":["If you have a custom listener adapter, filter empty lists before delegating to consumeMessage.","Ensure `consumeMessageBatchMaxSize` is a sane positive value (the code prefers 1 when relying on recoveryCallback).","Upgrade the RocketMQ client to match the broker version if empty batches recur."],"exampleFix":"// before\nadapter.consumeMessage(msgs, failSupplier, sucSupplier);\n// after\nif (CollectionUtils.isEmpty(msgs)) {\n    return sucSupplier.get(); // tolerate empty batch\n}\nadapter.consumeMessage(msgs, failSupplier, sucSupplier);","handlingStrategy":"validation","validationCode":"// Never hand an empty batch to the consumer path.\nif (!CollectionUtils.isEmpty(msgs)) {\n    consumeMessage(msgs, failSupplier, sucSupplier);\n}","typeGuard":null,"tryCatchPattern":null,"preventionTips":["Guard against empty/null batches at the listener boundary.","Prefer batchSize=1 when using recoveryCallback/DLQ wiring.","Keep RocketMQ client and broker versions aligned."],"tags":["rocketmq","consumer","batching","defensive"],"backgroundTag":null,"analyzedSha":"115d5901102009492e05d5ec18c3f79cad4077d0","analyzedAt":"2026-08-14T04:47:13.900Z","schemaVersion":2},"datasetVersion":"2026-08-14T05:17:29.042Z"}