Skip to content

Suspend @KafkaListener re-delivers a failing record without bound after DefaultErrorHandler retries are exhausted #4465

@lobodpav

Description

@lobodpav

In what version(s) of Spring for Apache Kafka are you seeing this issue?

4.1.0-M2 and 4.1.0-RC1 (with Spring Boot 4.1.0-M2 / 4.1.0-RC1). Not reproducible on 4.0.x.

Describe the bug

With a non-transactional container and a Kotlin suspend @KafkaListener configured with a DefaultErrorHandler(FixedBackOff(interval, n)), a record whose processing always fails is re-delivered without bound.

A blocking (non-suspend) listener with the identical configuration behaves as expected: it is delivered n + 1 times (initial delivery + n retries) and then stops.

For the suspend listener, the delivery count keeps growing indefinitely. With a DeadLetterPublishingRecoverer, a new DLT copy is published on every cycle.

To Reproduce

Minimal project: https://github.com/lobodpav/spring-kafka-retry-issue. No transactions, no @RetryableTopic, no custom recoverer — just Spring Boot + spring-kafka + a Testcontainers broker, with one blocking and one suspend @KafkaListener that always throw, and a DefaultErrorHandler(FixedBackOff(100L, 2L)).

Run ./gradlew test. One record is sent to each topic; the test asserts each listener is delivered 3 times. The blocking assertion passes; the suspend assertion fails because suspendDeliveries keeps growing.

Expected behavior

The suspend/async listener should behave like the blocking one: it is delivered n + 1 times and then stops; the record is not re-delivered after retries are exhausted.

Actual behavior

The record is re-delivered forever.

With FixedBackOff(100L, 2L) (initial delivery + 2 retries → expected 3 deliveries), and one record sent to each topic:

  • blockingDeliveries settles at 3 and stops.
  • suspendDeliveries keeps climbing (≈18–20 within 10s at a 100 ms back off) and never settles.

Sample

https://github.com/lobodpav/spring-kafka-retry-issue

Metadata

Metadata

Assignees

No one assigned

    Type

    No type
    No fields configured for issues without a type.

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions