skip to content

How can you expose a single health group on the main server port (not the management port) so a Kubernetes probe can reach it, and why would you?

level: seniorimportance: should knowfreq 14%

answer

  1. additional-path=server:/healthz
  2. groups only, not the base endpoint
  3. server: = main port, management: = mgmt port
  4. path is server-root relative, no /actuator prefix
  5. keeps full Actuator private, exposes just the probe

basics

~10 s

Set management.endpoint.health.group.<name>.additional-path=server:/healthz. That serves the group on the main application port at /healthz, in addition to its normal /actuator/health/<name> path.

solid answer

~40 s

When you run Actuator on a separate management port (`management.server.port`), the rest of the world — including Kubernetes probes or a load balancer — can only reach the app's main port. `additional-path` republishes ONE group on a chosen port. `management.endpoint.health.group.readiness.additional-path=server:/healthz` exposes that group at `/healthz` on the main server port, while it still lives at `/actuator/health/readiness` on the management port. The value is a prefix (`server:` or `management:`) plus an absolute path. Only health groups support this; you can't relocate arbitrary endpoints. The motivation: keep the full management surface private on an internal-only port, but selectively surface just the probe(s) the orchestrator needs on the public port — minimal exposure, no full Actuator on the internet.

code

yaml · 14 lines
yaml
server:
  port: 8080
management:
  server:
    port: 9001            # full Actuator stays private here
  endpoint:
    health:
      probes:
        enabled: true
      group:
        liveness:
          additional-path: server:/livez    # http://host:8080/livez
        readiness:
          additional-path: server:/readyz   # http://host:8080/readyz

go deeper

for a junior

Recognize additional-path exposes a group on another port; probably won't be asked deeply.

for a middle

State the server:/management: syntax and that only groups support it.

for a senior

Justify it as least-privilege probe exposure with a private management port, noting security-rule and path-collision pitfalls.

for a principal

Design the full split-port probe topology and reason about the security boundary between the public probe path and the private management surface.

## The management-port problem Actuator can run on its own port so operational endpoints aren't exposed alongside application traffic: ``` management.server.port=9001 server.port=8080 ``` Now `/actuator/**` answers on 9001. But a Kubernetes probe, an AWS ELB health check, or an external monitor typically hits the pod's main service port (8080). They may have no route to 9001. You need the probe reachable on 8080 without dragging the entire Actuator surface there. ## `additional-path` Health **groups** (only groups, not the base health endpoint or other endpoints) support an `additional-path`: ``` management.endpoint.health.group.readiness.additional-path=server:/healthz ``` This exposes the `readiness` group at `/healthz` on the **main server port** (8080), *in addition to* its normal `/actuator/health/readiness` on the management port. ### Value syntax The value is `<namespace>:<absolute-path>` where namespace is: - **`server:`** — the main application port (`server.port`). - **`management:`** — the management port (`management.server.port`). The path must start with `/` and is taken relative to the server root, NOT under the Actuator base path. So `server:/healthz` is literally `http://host:8080/healthz`, not `/actuator/healthz`. ## Why this design Minimal exposure / least privilege. Instead of moving the whole health endpoint (and everything else) to the public port, you surface exactly the probe subsets the orchestrator needs — often `liveness` and `readiness` — each on a clean, memorable public path, while `env`, `beans`, `heapdump`, `metrics`, etc. stay behind the private management port. ## Typical pairing with probes ``` management.server.port=9001 management.endpoint.health.probes.enabled=true management.endpoint.health.group.liveness.additional-path=server:/livez management.endpoint.health.group.readiness.additional-path=server:/readyz ``` Kubernetes `livenessProbe`/`readinessProbe` then point at `/livez` and `/readyz` on the container port. ## Gotchas - Only **groups** get `additional-path`; you cannot relocate `/actuator/health` itself or non-health endpoints this way. - The path is server-root relative — forgetting the leading `/` or expecting an `/actuator` prefix is a common mistake. - The group is still reachable at its original management path too; `additional-path` adds a location, it doesn't move it. - If you didn't split ports, `additional-path` is usually unnecessary — the group is already reachable at `/actuator/health/<name>`. - Watch for path collisions with real application routes on the main port (`/health`, `/healthz` must not clash with a controller). - Security config on the main port must permit the additional path (it's outside the Actuator base path, so a rule matching `/actuator/**` won't cover `/healthz`).

  • Can you use additional-path to move the base /actuator/health endpoint to the main port?
    No. additional-path is a property of health GROUPS only. To surface health on the main port you expose a group (or the auto-created liveness/readiness groups) with additional-path; the base endpoint itself has no such option.
  • Is /healthz from additional-path under the Actuator base path or the server root?
    Server root. server:/healthz resolves to http://host:8080/healthz, not /actuator/healthz — so your security rules for /actuator/** won't automatically cover it.

saying these in an interview costs you the question

  • Claiming any endpoint (not just groups) supports additional-path
  • Thinking the additional path lives under /actuator
  • Assuming additional-path MOVES the group rather than adding a location
  • Forgetting the main-port security config must permit the new path

context