GitHub
08/05/2026, 4:44 PM/health endpoint on osctrl-api always returned HTTP 200, even when the DB health monitor (wired in the preceding API outage-resistance change) had flipped EnvCache into stale-serve mode. Operators and load balancers had no way to distinguish a healthy osctrl-api from one that was serving cached data because the backend was down.
Change
HealthHandler now consults the wired backend.DegradedReader and returns HTTP 204 (no body) when the backend is degraded, instead of always returning 200. When no monitor is wired (or it reports healthy), the legacy 200 + "✅" body is unchanged. Mirrors the equivalent change already applied to osctrl-tls.
• cmd/api/handlers/get.go — HealthHandler checks `h.DBHealth.IsDegraded()`; on true it writes 204 and returns, otherwise the previous 200 path runs. The OpenAPI annotation is updated to advertise the new 204 success code.
• cmd/api/handlers/handlers.go — Added a DBHealth backend.DegradedReader field to HandlersApi and a WithDBHealth option.
• cmd/api/main.go — Wired handlers.WithDBHealth(dbHealth) at handler construction. dbHealth is nil when --db-health-check is disabled, so the field's nil check preserves the legacy behavior automatically.
• cmd/api/handlers/get_test.go (new) — Added TestHealthHandler_200 (no monitor → 200), TestHealthHandler_DegradedReturns204 (degraded → 204 + empty body), TestHealthHandler_DegradedReaderNilKeeps200 (nil monitor → 200, defense in depth), and TestHealthHandler_RecoveredReturns200 (monitor reports healthy → 200). A newHealthTestHandler helper initializes the DebugHTTPConfig the handler dereferences.
Why 204 and not 503
The service is still serving read paths from stale-serve caches — that is the whole point of the canary wired in the API outage-resistance change. Returning 503 would make load balancers drop traffic to a service that is intentionally still handling requests, defeating the outage resistance. 204 signals "degraded but alive" so operators/LBs can distinguish the state without failing the health check. Same rationale as the osctrl-tls health change.
Validation
• go build ./cmd/api/... — clean
• go vet ./cmd/api/... — clean
• go test ./cmd/api/... ./cmd/tls/... — all pass, including the four new tests in cmd/api/handlers/get_test.go
jmpsec/osctrlGitHub
08/05/2026, 4:55 PM