Production Patterns · Intermediate · Topic 5 of 5
Consumer with Message Headers
Kafka records can carry headers: small key-value metadata such as a trace ID or an event version. Spring can inject the record's topic, partition and offset, and your own headers, into listener parameters.
@Service
public class HeaderAwareConsumer {
// Inject specific headers via @Header
@KafkaListener(topics = "orders.order.created")
public void onOrder(
OrderEvent event,
@Header(KafkaHeaders.RECEIVED_TOPIC) String topic,
@Header(KafkaHeaders.RECEIVED_PARTITION) int partition,
@Header(KafkaHeaders.OFFSET) long offset,
@Header(name = "X-Trace-Id", required = false) String traceId,
@Header(name = "X-Event-Version", required = false) String eventVersion
) {
MDC.put("traceId", traceId != null ? traceId : "unknown");
log.info("Processing order from {}-{} @ offset {}", topic, partition, offset);
// process...
}
}
// Producer: add headers
@Service
public class TracingOrderProducer {
public void publish(Order order) {
var record = new ProducerRecord<>("orders.order.created",
null, System.currentTimeMillis(), order.getId(),
new OrderCreatedEvent(order));
record.headers()
.add(new RecordHeader("X-Trace-Id", TraceContext.current().toBytes()))
.add(new RecordHeader("X-Event-Version", "2".getBytes()))
.add(new RecordHeader("X-Source-Service", "order-service".getBytes()));
kafkaTemplate.send(record);
}
}Sources
- @KafkaListener annotation (Spring for Apache Kafka) (opens in a new tab)
- KafkaHeaders API (Spring for Apache Kafka) (opens in a new tab)
- Sending messages (Spring for Apache Kafka) (opens in a new tab)
- Change history (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.