alibaba/spring-cloud-alibaba · warning · MessagingException

DefaultMQPushConsumer consuming failed, Caused by messageExt

Error message

DefaultMQPushConsumer consuming failed, Caused by messageExtList is empty

What it means

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).

Source

Thrown at spring-cloud-alibaba-starters/spring-cloud-starter-stream-rocketmq/src/main/java/com/alibaba/cloud/stream/binder/rocketmq/integration/inbound/RocketMQInboundChannelAdapter.java:137

					"DefaultMQPushConsumer init failed, Caused by " + e.getMessage())
					.build(), e);
		}
	}

	/**
	 * The actual execution of a user-defined input consumption service method.
	 * @param messageExtList rocket mq message list
	 * @param failSupplier {@link ConsumeConcurrentlyStatus} or
	 *     {@link ConsumeOrderlyStatus}
	 * @param sucSupplier {@link ConsumeConcurrentlyStatus} or
	 *     {@link ConsumeOrderlyStatus}
	 * @param <R> object
	 * @return R
	 */
	private <R> R consumeMessage(List<MessageExt> messageExtList,
			Supplier<R> failSupplier, Supplier<R> sucSupplier) {
		if (CollectionUtils.isEmpty(messageExtList)) {
			throw new MessagingException(
					"DefaultMQPushConsumer consuming failed, Caused by messageExtList is empty");
		}
		// With consumeMessageBatchMaxSize > 1, a recoveryCallback that throws midway
		// through a batch causes the whole batch to be redelivered, so previously
		// recovered messages will be recovered again. Prefer batchSize=1 when relying
		// on recoveryCallback for DLQ wiring.
		for (MessageExt messageExt : messageExtList) {
			try {
				Message<?> message = RocketMQMessageConverterSupport
						.convertMessage2Spring(messageExt);
				if (this.retryTemplate != null) {
					try {
						this.retryTemplate.execute(() -> {
							this.sendMessage(message);
							return Boolean.TRUE;
						});
					}
					catch (RetryException retryException) {

View on GitHub (pinned to 115d590110)

Solutions

  1. If you have a custom listener adapter, filter empty lists before delegating to consumeMessage.
  2. Ensure `consumeMessageBatchMaxSize` is a sane positive value (the code prefers 1 when relying on recoveryCallback).
  3. Upgrade the RocketMQ client to match the broker version if empty batches recur.

Example fix

// before
adapter.consumeMessage(msgs, failSupplier, sucSupplier);
// after
if (CollectionUtils.isEmpty(msgs)) {
    return sucSupplier.get(); // tolerate empty batch
}
adapter.consumeMessage(msgs, failSupplier, sucSupplier);
Defensive patterns

Strategy: validation

Validate before calling

// Never hand an empty batch to the consumer path.
if (!CollectionUtils.isEmpty(msgs)) {
    consumeMessage(msgs, failSupplier, sucSupplier);
}

Prevention

When it happens

Trigger: The push MessageListener/consume path calls consumeMessage with an empty or null `messageExtList`.

Common situations: Misconfigured `consumeMessageBatchMaxSize`; a custom listener that manually forwards an empty list; broker/client version mismatch producing zero-length batches; the recoveryCallback path mishandling batches.

Related errors


AI-assisted analysis of alibaba/spring-cloud-alibaba@115d590110 (2026-08-14). Data as JSON: /api/errors/6451bb6695fb43ba. Report an issue: GitHub.