Skip to content
AITroveRead. Build. Understand.
Make this comfortable

Spring Cloud Stream Kafka DLQ: stop poison messages without losing the trail

Last updated: 1 Oct 20264 min read
tutorial
IntermediateBy AITrove Editorial

A Kafka binder dead-letter topic is an explicit failure route after configured attempts; it is not a fix for the failed record.

Bind failures to a named group

The Kafka binder's DLQ path needs a consumer group and explicit enablement. After the configured attempts are exhausted, a failing parcel message can be published to a dead-letter topic. The application must decide who inspects, repairs and replays that record. The listener failure lesson distinguishes transient errors from bad data.

Keep replay bounded

Attach the original event ID, failure class and attempt count to an operational record. A replay worker must not blindly put a permanently invalid message back on the main topic: that creates a loop. Send repaired records under a new correction ID or preserve the original ID with a documented dedup policy. Idempotency state and business uniqueness need to agree on that choice.

Verify the binder's actual behavior

Force one valid record to fail twice and then succeed; force another to fail beyond the limit. Assert the first reaches business state once and the second appears in the configured DLQ with enough context to repair it. This cannot be proven by a unit test of the Consumer function alone.

Implementation sketch

yaml
spring:
  cloud:
    stream:
      bindings:
        settleParcel-in-0:
          destination: parcel-events
          group: settlement-workers
          consumer:
            max-attempts: 3
      kafka:
        bindings:
          settleParcel-in-0:
            consumer:
              enable-dlq: true

Cost and verification

Each retry consumes processing capacity and can block later records on the same partition. DLQ storage grows until records are triaged and retained or removed under policy.

Common Mistakes

  • Do not expect DLQ routing without the binder-specific setting and named group.
  • Do not replay every DLQ record automatically.
  • Do not discard the original event ID or error reason during repair.

Read next

Spring Cloud Stream consumer group: scale one logical reader without copying every event, Spring Kafka listener failures: separate transient retries from poison records, Spring Integration idempotent receiver: the metadata key is not the business commit, Spring outbox retry budget: park a poison event for inspection.

spring
spring-boot
cloud
cloud-stream-kafka-dlq
Storage details