skip to content

How does Spring Boot compute the single overall health status from many contributors, and how is the severity ordering configured?

level: middleimportance: should knowfreq 55%

answer

  1. SimpleStatusAggregator = worst-wins
  2. Default order: DOWN, OUT_OF_SERVICE, UP, UNKNOWN
  3. status.order property = severity list
  4. Unknown codes sort last (alphabetical)
  5. Custom Status must be added to order

basics

~10 s

A StatusAggregator (default SimpleStatusAggregator) picks the most severe status among all contributors. The default order (most to least severe) is DOWN, OUT_OF_SERVICE, UP, UNKNOWN. You can override it with management.endpoint.health.status.order.

solid answer

~30 s

Each HealthContributor reports its own Status. Actuator combines them via a StatusAggregator bean — by default SimpleStatusAggregator — which sorts all reported statuses by a configured severity order and returns the most severe (first) one as the overall status. The default order, most-severe-first, is DOWN, OUT_OF_SERVICE, UP, UNKNOWN, so a single DOWN contributor makes the whole endpoint DOWN. You reorder severity with management.endpoint.health.status.order (a comma-separated list). Any status code not in the list sorts after the known ones (alphabetically), which matters when you introduce custom statuses — you must add them to the order or they'll be treated as least severe.

code

yaml · 6 lines
yaml
management:
  endpoint:
    health:
      status:
        # most-severe-first; custom FATAL now outranks DOWN
        order: FATAL,DOWN,OUT_OF_SERVICE,UP,UNKNOWN

go deeper

for a junior

Know that worst-status-wins and DOWN makes everything DOWN.

for a middle

Recite the default order and the status.order property.

for a senior

Explain how unlisted codes sort and why custom statuses need explicit ordering.

for a principal

Discuss per-group aggregators and when a custom StatusAggregator bean is warranted.

**The aggregation problem.** `/actuator/health` may have dozens of contributors (db, diskSpace, redis, custom ones). The endpoint must return a **single** overall `Status`. That collapse is done by a `StatusAggregator`. **SimpleStatusAggregator.** The default `StatusAggregator` bean is `SimpleStatusAggregator`. Given the set of all contributor status codes, it sorts them by a severity **order** and returns the **first** (most severe) as the aggregate. So the rule is effectively "worst wins": one `DOWN` contributor drags the whole endpoint to `DOWN`. **The default order.** From most severe to least severe: `DOWN`, `OUT_OF_SERVICE`, `UP`, `UNKNOWN`. (Note that `UNKNOWN` is considered *less* severe than `UP` here — an unknown component alone won't pull the endpoint below UP, whereas a DOWN one will.) **How ordering resolves unknown codes.** The comparator inside `SimpleStatusAggregator` assigns each status its index in the configured order list. Status codes **not present** in the list are placed **after** all listed codes, and ties among unlisted codes are broken by the natural (alphabetical) ordering of the code string. This is the key gotcha for custom statuses: if you register a custom `Status("FATAL")` but do **not** add it to the order, `FATAL` sorts after `DOWN`/`UP`/etc. and is treated as the *least* severe — the opposite of what you usually want. **Configuring the order.** Set `management.endpoint.health.status.order` as a comma-separated list, most-severe-first, e.g. `FATAL,DOWN,OUT_OF_SERVICE,UP,UNKNOWN`. This is the standard way to make a custom status outrank the built-ins. **Providing a custom aggregator.** For logic that can't be expressed as a simple order (e.g. "UP only if a quorum of contributors is UP"), you can define your own `StatusAggregator` bean; the custom bean replaces `SimpleStatusAggregator`. This is rarely needed. **Groups.** Health groups (`management.endpoint.health.group.*`) can each have their own `StatusAggregator`, so a liveness group and a readiness group can aggregate differently — but the same ordering mechanism applies within each. **Common gotchas.** - Assuming `UNKNOWN` is more severe than `UP` — it is not, by default it is the *least* severe. - Forgetting that custom statuses default to least-severe until added to `status.order`. - Confusing the *aggregation order* (which status wins) with the *HTTP mapping* (which code that status returns) — those are two separate settings (`status.order` vs `status.http-mapping`).

  • If one contributor is DOWN and all others are UP, what is the overall status by default?
    DOWN. SimpleStatusAggregator returns the most severe status, and DOWN is first in the default order, so a single DOWN wins.
  • You add a custom Status("FATAL") but the endpoint still reports UP when FATAL is present. Why?
    Because FATAL is not in status.order, so it's treated as least-severe (sorted after the known codes). Add it to management.endpoint.health.status.order ahead of UP.

saying these in an interview costs you the question

  • Claiming UNKNOWN is more severe than UP
  • Saying the aggregator averages or votes rather than picking the worst
  • Assuming custom statuses are automatically most-severe

context