Production Patterns · Intermediate · Topic 1 of 5
DefaultErrorHandler with Dead Letter Topic
DefaultErrorHandler is the container's default error handler. It retries a failed record by seeking back to it, following a BackOff, and when retries are exhausted it calls a recoverer. The default is FixedBackOff(0L, 9) and logging; DeadLetterPublishingRecoverer publishes the failed record to <topic>-dlt (the same partition, by default).
@Configuration
@Slf4j
public class KafkaConsumerConfig {
@Bean
public ConcurrentKafkaListenerContainerFactory<String, Object> kafkaListenerContainerFactory(
ConsumerFactory<String, Object> consumerFactory,
KafkaTemplate<String, Object> kafkaTemplate
) {
var factory = new ConcurrentKafkaListenerContainerFactory<String, Object>();
factory.setConsumerFactory(consumerFactory);
factory.getContainerProperties().setAckMode(ContainerProperties.AckMode.MANUAL_IMMEDIATE);
// DeadLetterPublishingRecoverer sends failed records to {topic}-dlt, same partition
var recoverer = new DeadLetterPublishingRecoverer(kafkaTemplate,
(record, ex) -> new TopicPartition(record.topic() + "-dlt", record.partition()));
// 3 retries with exponential back off (1 s, 2 s, 4 s, capped at 10 s), then the recoverer
var backOff = new ExponentialBackOffWithMaxRetries(3);
backOff.setInitialInterval(1_000L);
backOff.setMultiplier(2.0);
backOff.setMaxInterval(10_000L);
var errorHandler = new DefaultErrorHandler(recoverer, backOff);
// Add exception types that must not be retried: they go straight to the recoverer
errorHandler.addNotRetryableExceptions(IllegalArgumentException.class);
// With MANUAL_IMMEDIATE, commit the offset of a record the recoverer handled
errorHandler.setCommitRecovered(true);
factory.setCommonErrorHandler(errorHandler);
factory.setConcurrency(3);
return factory;
}
}Sources
- Handling exceptions (Spring for Apache Kafka) (opens in a new tab)
- Listener container properties (Spring for Apache Kafka) (opens in a new tab)
- Message listener containers (Spring for Apache Kafka) (opens in a new tab)
Checked against Spring for Apache Kafka 4.1.1, Spring Boot 4.1.1 and Kafka 4.2 documentation on 11 October 2026. Draft: not yet reviewed by a Kafka specialist, and releases move on, so confirm against the current documentation before you act on it.