Skip to content

Spring Boot Health Check — Complete Implementation Guide

DodaTech Updated 2026-06-28 6 min read

In this tutorial, you will learn about Spring Boot Health Check. We cover key concepts, practical examples, and best practices to help you master this topic.

Spring Boot Actuator provides built-in health check endpoints that automatically detect available dependencies like databases, caches, and message brokers, with extensible health indicators for custom components.

What You'll Learn

By the end of this tutorial, you will know how to configure Spring Boot Actuator health checks, create custom health indicators, set up liveness and readiness probes, and integrate with Kubernetes.

Why It Matters

Spring Boot is the most popular Java framework for Microservices. Actuator health checks are the standard way to expose health information for Spring Boot applications in production.

Real-World Use

Durga Antivirus Pro's scanning API is built with Spring Boot. Its health endpoint checks the signature database, virus definition cache, and file storage service, reporting detailed status for each.

Spring Boot Health Check Learning Path

flowchart LR
  A[Go Health Check] --> B[Spring Boot Health Check]
  B --> C[Actuator Setup]
  B --> D[Custom Indicators]
  B --> E[Kubernetes Probes]
  B --> F{You Are Here}
  style F fill:#f90,color:#fff

Actuator Configuration

Spring Boot Actuator health endpoints require minimal configuration.

# application.yml
management:
  endpoints:
    web:
      exposure:
        include: health,info
  endpoint:
    health:
      show-details: always
      show-components: always
      probes:
        enabled: true
  health:
    readinessstate:
      enabled: true
    livenessstate:
      enabled: true
// No code needed for the basic health endpoint
// The /actuator/health endpoint is auto-configured

// GET /actuator/health
// {
//   "status": "UP",
//   "components": {
//     "db": { "status": "UP", "details": { "database": "PostgreSQL", "validationQuery": "isValid()" } },
//     "diskSpace": { "status": "UP", "details": { "total": 1000000, "free": 500000 } },
//     "ping": { "status": "UP" }
//   }
// }

Custom Health Indicator

Create custom health indicators for application-specific dependencies.

package com.dodatech.health;

import org.springframework.boot.actuate.health.Health;
import org.springframework.boot.actuate.health.HealthIndicator;
import org.springframework.stereotype.Component;
import org.springframework.web.client.RestTemplate;

@Component
public class SignatureDatabaseHealthIndicator implements HealthIndicator {

    private final RestTemplate restTemplate;

    public SignatureDatabaseHealthIndicator(RestTemplate restTemplate) {
        this.restTemplate = restTemplate;
    }

    @Override
    public Health health() {
        try {
            var response = restTemplate.getForEntity(
                "https://signatures.dodatech.com/health",
                String.class
            );

            if (response.getStatusCode().is2xxSuccessful()) {
                return Health.up()
                    .withDetail("service", "signature-database")
                    .withDetail("latencyMs", "15")
                    .build();
            }

            return Health.down()
                .withDetail("service", "signature-database")
                .withDetail("statusCode", response.getStatusCodeValue())
                .build();
        } catch (Exception e) {
            return Health.down(e)
                .withDetail("service", "signature-database")
                .build();
        }
    }
}

Liveness and Readiness Probes

Spring Boot 3 provides dedicated health groups for Kubernetes probes.

# application.yml
management:
  endpoint:
    health:
      probes:
        enabled: true
  health:
    livenessstate:
      enabled: true
    readinessstate:
      enabled: true
// Liveness probe endpoint: /actuator/health/liveness
// Returns 200 if the application is internally healthy
// Returns 503 if the application needs restarting

// Readiness probe endpoint: /actuator/health/readiness
// Returns 200 if the application is ready to serve traffic
// Returns 503 if the application is not ready (e.g., during startup or dependency failure)

@Configuration
public class ProbeConfiguration {

    @Bean
    public HealthIndicator databaseReadinessIndicator(DataSource dataSource) {
        return () -> {
            try (var connection = dataSource.getConnection()) {
                if (connection.isValid(2)) {
                    return Health.up().build();
                }
                return Health.down().withDetail("reason", "Database connection invalid").build();
            } catch (Exception e) {
                return Health.down(e).build();
            }
        };
    }
}

Composite Health Indicator

Group multiple related health checks into a composite indicator.

@Component
public class CacheLayerHealthIndicator implements HealthIndicator {

    private final List<CacheHealthChecker> checkers;

    public CacheLayerHealthIndicator(List<CacheHealthChecker> checkers) {
        this.checkers = checkers;
    }

    @Override
    public Health health() {
        var builder = Health.up();
        boolean allHealthy = true;

        for (var checker : checkers) {
            try {
                var result = checker.check();
                if (!result.isHealthy()) {
                    allHealthy = false;
                }
                builder.withDetail(checker.getName(), result);
            } catch (Exception e) {
                allHealthy = false;
                builder.withDetail(checker.getName(), "error: " + e.getMessage());
            }
        }

        return allHealthy ? builder.build() : builder.down().build();
    }

    interface CacheHealthChecker {
        String getName();
        CacheCheckResult check();
    }

    record CacheCheckResult(boolean isHealthy, long latencyMs) {}
}

Health Endpoint Security

Configure security for health endpoints in production.

// SecurityConfiguration.java
@Configuration
public class SecurityConfiguration {

    @Bean
    public SecurityFilterChain filterChain(HttpSecurity http) throws Exception {
        http
            .authorizeHttpRequests(auth -> auth
                .requestMatchers("/actuator/health/**").permitAll()
                .requestMatchers("/actuator/info").permitAll()
                .requestMatchers("/actuator/**").hasRole("ADMIN")
                .anyRequest().authenticated()
            );
        return http.build();
    }
}

// application.yml
management:
  endpoints:
    web:
      exposure:
        include: health,info,metrics
  endpoint:
    health:
      show-details: when-authorized
      roles: ADMIN

Common Mistakes

  1. Exposing all Actuator endpoints in production -- /actuator/env, /actuator/configprops, and /actuator/beans can leak sensitive information. Only expose health and info in production.

  2. Not setting show-details properly -- show-details: always reveals dependency details to anyone. Use show-details: when-authorized with appropriate roles in production.

  3. Forgetting to enable probes -- In Spring Boot 3, liveness and readiness probes are disabled by default. Set management.endpoint.health.probes.enabled: true.

  4. Making health indicators throw exceptions -- Health indicators should catch all exceptions and return Health.down(), not throw. An uncaught exception makes the entire health endpoint fail.

  5. Not testing custom health indicators -- Custom indicators have bugs too. Write unit tests that verify they return Up, Down, and Unknown status correctly.

Practice Questions

  1. What dependency is needed for Spring Boot Actuator health checks? spring-boot-starter-actuator. It auto-configures the health endpoint and built-in health indicators.

  2. How do you create a custom health indicator? Implement the HealthIndicator interface and register it as a Spring bean. The health() method returns a Health object.

  3. What is the difference between LivenessStateHealthIndicator and ReadinessStateHealthIndicator? Liveness indicates the application is internally healthy and doesn't need restarting. Readiness indicates the application can serve traffic.

  4. Challenge: Implement a health indicator that aggregates multiple sub-checks and reports degraded status if any sub-check fails.

@Component
public class AggregatedHealthIndicator implements HealthIndicator {

    private final List<HealthIndicator> indicators;

    public AggregatedHealthIndicator(List<HealthIndicator> indicators) {
        this.indicators = indicators;
    }

    @Override
    public Health health() {
        var builder = Health.up();
        int up = 0, down = 0;

        for (var indicator : indicators) {
            try {
                var health = indicator.health();
                if (health.getStatus() == Status.UP) {
                    up++;
                } else {
                    down++;
                }
            } catch (Exception e) {
                down++;
            }
        }

        builder.withDetail("up", up);
        builder.withDetail("down", down);

        return down == 0 ? builder.build() : builder.down().build();
    }
}

FAQ

What is the default health endpoint path in Spring Boot?

/actuator/health. The base path can be changed with management.endpoints.web.base-path.

Which built-in health indicators does Spring Boot include?

DataSource, Mongo, Redis, RabbitMQ, Kafka, Elasticsearch, Cassandra, Couchbase, LDAP, and more. They auto-configure when the corresponding dependency is on the classpath.

How do I disable a specific health indicator?

Set management.health..enabled: false in application.yml. For example, management.health.mongo.enabled: false.

Can I add custom HTTP headers to the health response?

No, but you can add custom details in the Health object returned by your HealthIndicator. Use withDetail() to add key-value pairs.

How does Spring Boot 3 handle Kubernetes probes?

Spring Boot 3 has built-in support for liveness and readiness probes. Enable them with management.endpoint.health.probes.enabled: true.

Mini Project

Build a Spring Boot application with Actuator health checks, custom health indicators for database and external API, liveness and readiness probe endpoints, and proper security configuration.

@SpringBootApplication
public class HealthCheckApplication {

    public static void main(String[] args) {
        SpringApplication.run(HealthCheckApplication.class, args);
    }

    @Bean
    public HealthIndicator customCheck() {
        return () -> Health.up()
            .withDetail("service", "custom")
            .withDetail("version", "1.0.0")
            .build();
    }
}

What's Next

Now that you understand Spring Boot health checks, learn about Kubernetes probe configuration. Then explore custom health indicators in depth.

Built by the developers of DodaTech

Doda Browser, DodaZIP & Durga Antivirus Pro