Spring Actuator + Kafka Streams - Add kafka stream status to health check endpoint
Master System Design with Codemia
Enhance your system design skills with over 120 practice problems, detailed solutions, and hands-on exercises.
Introduction
To surface Kafka Streams state in Spring Boot Actuator, expose a health contributor that reads the current stream state and maps it to an Actuator status. The main design question is not how to call the API, but how to decide which Kafka Streams states should count as healthy, degraded, or down for your deployment model.
Where to read the Kafka Streams state
If your application manages KafkaStreams directly, you can inject that instance into a HealthIndicator. In Spring-managed Kafka Streams applications, another common option is to obtain the runtime instance from StreamsBuilderFactoryBean, which is the bean Spring Kafka uses to create and start the streams client.
A basic health indicator looks like this:
The state mapping is the important part. RUNNING is healthy. REBALANCING is often still healthy enough for liveness, but it may not be ready for traffic if you use the health check to gate readiness.
Using StreamsBuilderFactoryBean in Spring Kafka
When Spring creates the streams client for you, there may not be a directly injectable KafkaStreams bean at startup time. In that case, build the health indicator around StreamsBuilderFactoryBean and handle the case where the runtime instance has not been started yet.
That example keeps the wiring realistic for Spring Kafka applications and prevents a null failure during application startup.
Exposing the health endpoint cleanly
Actuator still has to expose the health endpoint and, if you want to see the details, it has to be configured to show them.
If you use Kubernetes, you can keep the same health contributor and then decide whether it belongs in the readiness group, the liveness group, or only the general health endpoint. Readiness is the usual choice because a stream app that is rebalancing may still be alive even if it should not yet receive traffic.
Choosing a status policy that matches operations
Do not blindly map every non-RUNNING state to DOWN. That often creates noisy alerts during normal rebalances and rolling deploys. A better approach is to separate operational states into three categories:
- healthy enough to serve:
RUNNING - alive but temporarily unstable:
REBALANCING, sometimesCREATED - failed or stopped:
ERROR,NOT_RUNNING
If the health endpoint feeds a dashboard, you may keep REBALANCING as UP and rely on the details field. If it feeds readiness checks, OUT_OF_SERVICE is often a better signal because it removes the pod from service without triggering a restart loop.
Spring Cloud Stream binder note
If the application uses the Spring Cloud Stream Kafka Streams binder instead of managing the streams runtime directly, first check what binder health information is already available. In that setup, Actuator integration may already include binder-specific health contributors, and a custom indicator may only be necessary if you want a different status policy or more detailed metadata.
That distinction matters because the correct extension point depends on which Spring stack is actually starting and owning the Kafka Streams instance.
Common Pitfalls
A common mistake is injecting KafkaStreams directly even though the application lifecycle is managed through StreamsBuilderFactoryBean, which can leave you with null or timing issues.
Another mistake is treating REBALANCING as a hard failure. That usually produces false alarms during healthy cluster activity.
A third mistake is forgetting Actuator exposure settings, then assuming the health indicator is broken because the endpoint does not show any details.
Summary
- Expose Kafka Streams state through a custom
HealthIndicatororHealthContributor. - Read the runtime from
KafkaStreamsdirectly only when your application really owns that instance. - Use
StreamsBuilderFactoryBeanin Spring Kafka applications that let Spring create the streams client. - Map Kafka Streams states to health statuses based on how the endpoint is used operationally.
- Expose health details and place the contributor in the right readiness or liveness context.

