🔴 The Error You're Seeing

Confirm this matches your console output. If it does, you're in the right place.

ERROR LOGorg.springframework.amqp.rabbit.support.ListenerExecutionFailedException: Listener method could not be invoked with the incoming message at org.springframework.amqp.rabbit.listener.adapter.MessagingMessageListenerAdapter.invokeHandler(MessagingMessageListenerAdapter.java:203) Caused by: org.springframework.amqp.support.converter.MessageConversionException: failed to convert serialized payload

⚡ Quick Fix Works 80% of the time

Ensure a Jackson2JsonMessageConverter bean is configured and the listener expects the correct Java type.

@Bean public Jackson2JsonMessageConverter jsonMessageConverter() { return new Jackson2JsonMessageConverter(); }

🧠 Why this Happens

Tap to expand the deep technical explanation

Your `@RabbitListener` method received a message, but the payload couldn't be converted to the target Java object, or the listener method threw an unhandled exception. By default, Spring uses simple Java serialization. If the producer sent JSON, Spring fails to deserialize it into your POJO, causing the listener to crash and reject the message.

The HITEC City Parking Spot Analogy:

A factory receiving raw materials, but the assembly machine expects plastic and receives wood. The machine jams and rejects the material because it can't process it.

🔁 How to Reproduce Confirm this is your error

Configure a `@RabbitListener` expecting a `User` object. Send a plain text message or a JSON string without a `__TypeId__` header using the RabbitMQ admin UI. The listener will throw this exception.

🛠️ Solutions (5 Ways to Fix)

Solution 1✓ Most common cause

Configure a Jackson JSON Converter

👉 Use this when sending and receiving JSON payloads.

By default, Spring AMQP uses Java serialization. You must explicitly configure a `Jackson2JsonMessageConverter` bean and attach it to the listener container factory.

@Bean public Jackson2JsonMessageConverter jsonMessageConverter() { return new Jackson2JsonMessageConverter(); } @Bean public SimpleRabbitListenerContainerFactory rabbitListenerContainerFactory(ConnectionFactory connectionFactory, Jackson2JsonMessageConverter converter) { SimpleRabbitListenerContainerFactory factory = new SimpleRabbitListenerContainerFactory(); factory.setConnectionFactory(connectionFactory); factory.setMessageConverter(converter); return factory; }
Solution 2

Fix the content_type property

👉 Use this if the converter is configured but the message still fails.

Ensure the producer sets the `content_type` message property to `application/json`. Spring uses this to decide how to parse the body.

MessageProperties props = MessagePropertiesBuilder.newInstance().setContentType("application/json").build(); Message msg = new Message(jsonBytes, props); amqpTemplate.send("queue", msg);
Solution 3

Add a Dead Letter Queue (DLQ)

👉 Use this to prevent poison pills from blocking your queue indefinitely.

Configure the queue with `x-dead-letter-exchange` so messages that fail processing are routed to a DLQ instead of crashing the listener.

@Bean public Queue myQueue() { return QueueBuilder.durable("myQueue") .withArgument("x-dead-letter-exchange", "dlx.exchange") .build(); }
Solution 4

Catch the exception inside the listener

👉 Use this if you want to handle errors gracefully without rejecting the message.

Wrap your listener logic in a try-catch block to prevent Spring from throwing the exception up the stack.

@RabbitListener(queues = "myQueue") public void listen(User user) { try { process(user); } catch (Exception e) { log.error("Failed", e); // Do not rethrow, acknowledge the message } }
Solution 5

Change listener signature to String

👉 Use this if you are debugging and want to see the raw payload.

Accept the raw body as a String to inspect exactly what the producer sent before Spring attempts to map it to an object.

@RabbitListener(queues = "myQueue") public void listen(String rawMessage) { log.info("Raw payload: {}", rawMessage); }

📋 Version Notes

Spring Boot 2.x

Uses spring-amqp 2.x.

Spring Boot 3.x

Uses spring-amqp 3.x. Requires explicit listener container factory configuration.

🛡️ How to Prevent This Next Time

Always standardize your message converters on both the producer and consumer sides. Use JSON over Java serialization for forward compatibility.