I need to access the retry attempt number in spring cloud stream kafka transactional retry so that for a particular exception, based on the retry attempt number i can post the outcome to different topic
Asked
Active
Viewed 346 times
1 Answers
1
I assume you mean the delivery attempt in the consumer; you can use a ContainerCustomizer
bean to set the deliveryAttemptHeader
property to true.
/**
* Set to true to populate the
* {@link org.springframework.kafka.support.KafkaHeaders#DELIVERY_ATTEMPT} header when
* the error handler or after rollback processor implements
* {@code DeliveryAttemptAware}. There is a small overhead so this is false by
* default.
* @param deliveryAttemptHeader true to populate
* @since 2.5
*/
public void setDeliveryAttemptHeader(boolean deliveryAttemptHeader) {
this.deliveryAttemptHeader = deliveryAttemptHeader;
}
Then consume the entire Message<?>
to examine the header.

Gary Russell
- 166,535
- 14
- 146
- 179
-
Thanks for the direction, seems like a header deliveryAttempt is also added when we enable deliver attempt header, I see below headers `[headers={kafka_offset=5, scst_nativeHeadersPresent=true, kafka_consumer=org.apache.kafka.clients.consumer.KafkaConsumer@57d17787, deliveryAttempt=2, kafka_timestampType=CREATE_TIME, kafka_deliveryAttempt=[B@4d5c78b0, kafka_receivedPartitionId=4, kafka_receivedTopic=eu_ethoca_alertpersist, kafka_receivedTimestamp=1664455663685, contentType=application/*+avro, kafka_groupId=aps-processAlertQueueItem-test, target-protocol=streamBridge}]` – DreamCoder Sep 29 '22 at 13:03
-
That is a different count - that is a Spring Integration header, used when a `RetryTemplate` performs retrys. The kafka_deliveryAttempt is generated by the listener container; you should not configure both sets of retrys; otherwise they will be compounded; we recommend disabling retry in the binder (`maxAttempts=1`) and configuring the listener container to do the retries. – Gary Russell Sep 29 '22 at 14:06
-
In header `kafka_deliveryAttempt` I don't see any count, am I missing something? Also, we are not using `RetryTemplate` and just relying on transactional binder as mentioned in https://docs.spring.io/spring-cloud-stream-binder-kafka/docs/current/reference/html/spring-cloud-stream-binder-kafka.html#kafka-transactional-binder – DreamCoder Sep 30 '22 at 04:41
-
It's in binary form there; use `ByteBuffer.wrap(message.getHeaders().get(KafkaHeaders.DELIVERY_ATTEMPT), byte[].class).getInt()`. `maxattempts` is 3 by default, enabling retry in the binder; set it to 1 to disable. – Gary Russell Sep 30 '22 at 13:45
-
Please open an issue in spring-integration; the way we map the headers is inconsistent when a retry template exists or not. – Gary Russell Sep 30 '22 at 14:40
-
1Here's the bottom line - when binder retries are enabled (default), `deliveryAttempt` contains the binder retry count; when retries are disabled, the `kafka_deliveryAttempt` is decoded into `deliveryAttempt`; in both cases, `kafka_deliveryAttempt` (binary) is present. – Gary Russell Sep 30 '22 at 15:14