Summary
GET /health and GET /healthz can return Control UI HTML with 200 OK instead of machine-readable health JSON.
This makes deployment health probes (e.g. Render health checks) report healthy even when they are effectively checking the UI shell, not gateway/runtime dependency health.
Environment
- OpenClaw gateway running with Control UI enabled
- Observed on macOS Nimbus runtime during production audit
- Deployment config used
healthCheckPath: /health
Reproduction
- Run gateway with Control UI enabled.
- Probe endpoints directly:
curl -sS -D - http://127.0.0.1:18789/health -o /tmp/health.body
curl -sS -D - http://127.0.0.1:18789/healthz -o /tmp/healthz.body
- Inspect headers/body.
Expected
/healthz returns machine-parsable health payload (application/json) with meaningful status semantics.
/health should either alias to same JSON health payload or be explicitly documented/segregated from deployment probe paths.
Actual
Both /health and /healthz returned:
HTTP/1.1 200 OK
Content-Type: text/html; charset=utf-8
- Control UI HTML document (
<!doctype html> ... <title>OpenClaw Control</title> ...)
Evidence snippet
/health headers observed:
HTTP/1.1 200 OK
Content-Type: text/html; charset=utf-8
/health body starts with:
<!doctype html>
<html lang="en">
<head>
<title>OpenClaw Control</title>
Same behavior observed for /healthz.
Impact
- False-positive deployment health state.
- Operators cannot safely use
/health//healthz as runtime probes.
- Monitoring semantics diverge from expected health contract.
Related
Summary
GET /healthandGET /healthzcan return Control UI HTML with200 OKinstead of machine-readable health JSON.This makes deployment health probes (e.g. Render health checks) report healthy even when they are effectively checking the UI shell, not gateway/runtime dependency health.
Environment
healthCheckPath: /healthReproduction
curl -sS -D - http://127.0.0.1:18789/health -o /tmp/health.bodycurl -sS -D - http://127.0.0.1:18789/healthz -o /tmp/healthz.bodyExpected
/healthzreturns machine-parsable health payload (application/json) with meaningful status semantics./healthshould either alias to same JSON health payload or be explicitly documented/segregated from deployment probe paths.Actual
Both
/healthand/healthzreturned:HTTP/1.1 200 OKContent-Type: text/html; charset=utf-8<!doctype html> ... <title>OpenClaw Control</title> ...)Evidence snippet
/healthheaders observed:HTTP/1.1 200 OKContent-Type: text/html; charset=utf-8/healthbody starts with:Same behavior observed for
/healthz.Impact
/health//healthzas runtime probes.Related