How Does Spring Cloud Stream’s Built‑In Retry Handle Message Failures?

This article explains Spring Cloud Stream’s default retry mechanism, demonstrates a complete example of producing and consuming messages with intentional failures, shows how to configure retry attempts, and discusses what happens when retries succeed or ultimately fail, providing practical guidance for reliable message processing.

Programmer DD
Programmer DD
Programmer DD
How Does Spring Cloud Stream’s Built‑In Retry Handle Message Failures?

Previously I wrote about common issues when using Spring Cloud Stream, such as handling duplicate consumption and consuming messages produced by oneself. In the next few days I will focus on how to deal with message consumption failures.

Application Scenario

Retry can solve failures caused by external factors like network glitches when calling a Web Service after receiving a message. By retrying the consumer logic, the next attempt may succeed and complete the business action.

Hands‑On Example

Below is a minimal Spring Boot application that demonstrates the default retry mechanism. It includes a producer endpoint and a consumer that deliberately throws an exception to simulate failure.

@EnableBinding(TestApplication.TestTopic.class)
@SpringBootApplication
public class TestApplication {
    public static void main(String[] args) {
        SpringApplication.run(TestApplication.class, args);
    }

    @RestController
    static class TestController {
        @Autowired
        private TestTopic testTopic;

        @GetMapping("/sendMessage")
        public String messageWithMQ(@RequestParam String message) {
            testTopic.output().send(MessageBuilder.withPayload(message).build());
            return "ok";
        }
    }

    @Slf4j
    @Component
    static class TestListener {
        @StreamListener(TestTopic.INPUT)
        public void receive(String payload) {
            log.info("Received: " + payload);
            throw new RuntimeException("Message consumer failed!");
        }
    }

    interface TestTopic {
        String OUTPUT = "example-topic-output";
        String INPUT = "example-topic-input";
        @Output(OUTPUT)
        MessageChannel output();
        @Input(INPUT)
        SubscribableChannel input();
    }

Running the application and calling http://localhost:8080/sendMessage?message=hello produces three "Received: hello" logs, after which the consumer finally throws an exception.

Configuration

Spring Cloud Stream retries three times by default. You can change the number of attempts with:

spring.cloud.stream.bindings.example-topic-input.consumer.max-attempts=1

For pure computational logic where retries are useless, set the value to 0 to avoid unnecessary delays.

Deep Thinking

Question 1: If a retry eventually succeeds, will an exception still be logged?

Answer: No. A successful retry marks the whole consumption as successful, so no error is recorded.

To verify, modify the listener to count attempts and only throw an exception on the first two attempts:

@Slf4j
@Component
static class TestListener {
    int counter = 1;
    @StreamListener(TestTopic.INPUT)
    public void receive(String payload) {
        log.info("Received: " + payload + ", " + counter);
        if (counter == 3) {
            counter = 1;
            return;
        } else {
            counter++;
            throw new RuntimeException("Message consumer failed!");
        }
    }
}

Running this version shows three logs with counters 1, 2, 3 and no error stack trace.

Question 2: What should be done when all retries fail?

Currently the only option is to log the exception and alert operators, who can then take remedial actions based on the logged message details. More sophisticated handling (e.g., dead‑letter queues) would require additional configuration.

--- End of technical guide ---

Original Source

Signed-in readers can open the original source through BestHub's protected redirect.

Sign in to view source
Republication Notice

This article has been distilled and summarized from source material, then republished for learning and reference. If you believe it infringes your rights, please contactadmin@besthub.devand we will review it promptly.

springretrymessage-consumptionspring-bootspring-cloud-stream
Programmer DD
Written by

Programmer DD

A tinkering programmer and author of "Spring Cloud Microservices in Action"

0 followers
Reader feedback

How this landed with the community

Sign in to like

Rate this article

Was this worth your time?

Sign in to rate
Discussion

0 Comments

Thoughtful readers leave field notes, pushback, and hard-won operational detail here.