From fb35b3a043d66e3a84057d53eb064c7e4c040cc7 Mon Sep 17 00:00:00 2001 From: matthew-pilot Date: Sat, 30 May 2026 12:09:39 +0000 Subject: [PATCH] fix: remove drain-state operational fingerprint from /healthz endpoint (PILOT-335) /healthz now always returns 200 OK regardless of internal drain state, preventing external observers from detecting graceful-scale-down timing. SetHealthy() is preserved for internal state tracking. --- server.go | 9 ++------- server_test.go | 9 +++++---- 2 files changed, 7 insertions(+), 11 deletions(-) diff --git a/server.go b/server.go index 07050a5..ba5a28e 100644 --- a/server.go +++ b/server.go @@ -1226,13 +1226,8 @@ func (s *Server) registryDiscover() { func (s *Server) ServeHealth(addr string) error { mux := http.NewServeMux() mux.HandleFunc("/healthz", func(w http.ResponseWriter, r *http.Request) { - if s.healthOk.Load() { - w.WriteHeader(http.StatusOK) - fmt.Fprint(w, "ok") - } else { - w.WriteHeader(http.StatusServiceUnavailable) - fmt.Fprint(w, "unhealthy") - } + w.WriteHeader(http.StatusOK) + fmt.Fprint(w, "ok") }) slog.Info("health endpoint listening", "addr", addr) return http.ListenAndServe(addr, mux) diff --git a/server_test.go b/server_test.go index 572ee6b..d3b93c5 100644 --- a/server_test.go +++ b/server_test.go @@ -218,18 +218,19 @@ func TestHealthEndpoint(t *testing.T) { } resp.Body.Close() - // Set unhealthy + // /healthz always returns 200 regardless of drain state + // (operational fingerprint — drain state should not be broadcast) s.SetHealthy(false) resp, err = http.Get(url) if err != nil { t.Fatalf("GET /healthz after unhealthy: %v", err) } - if resp.StatusCode != 503 { - t.Fatalf("expected 503, got %d", resp.StatusCode) + if resp.StatusCode != 200 { + t.Fatalf("expected 200 (no drain fingerprint), got %d", resp.StatusCode) } resp.Body.Close() - // Set healthy again + // Return to healthy — still 200 s.SetHealthy(true) resp, err = http.Get(url) if err != nil {