Skip to content

fix: honor BackendConfigPolicy health check host on static backends#14201

Merged
puertomontt merged 3 commits into
kgateway-dev:mainfrom
puertomontt:fix/static-backend-healthcheck-host-override
Jun 23, 2026
Merged

fix: honor BackendConfigPolicy health check host on static backends#14201
puertomontt merged 3 commits into
kgateway-dev:mainfrom
puertomontt:fix/static-backend-healthcheck-host-override

Conversation

@puertomontt

@puertomontt puertomontt commented Jun 8, 2026

Copy link
Copy Markdown
Contributor

Description

The static backend plugin stamps each endpoint's health_check_config.hostname with the backend's dial address. Per Envoy semantics, a non-empty endpoint-level hostname overrides the cluster-level http_health_check.host. As a result, an explicitly configured BackendConfigPolicy.healthCheck.http.host was silently ignored: the cluster-level health check was set correctly, but the endpoint-level hostname (the backend's DNS dial address) took precedence, so health checks were sent with the wrong Host header.

For backends that route on the Host header (e.g. AWS ALBs, host-routing proxies), this marks all endpoints unhealthy and causes 503s.

Fix

When a BackendConfigPolicy configures a health check host (HTTP host or gRPC authority), clear the auto-stamped endpoint-level hostname in processBackend so the configured cluster-level value governs. When no host is configured, the endpoint hostname is preserved as a sensible default (the backend's real hostname rather than the internal cluster name), keeping prior behavior.

This is the reconciliation point where both the backend's dial address (set by the backend plugin) and the configured health check host (from the policy) are first available together. It restores the Gloo Edge v1 behavior, where the static plugin overrode the endpoint hostname with the configured health check host inline — logic that was dropped when health-check config moved from the monolithic Upstream spec into the separate BackendConfigPolicy CRD.

Regression

This was a regression from Gloo Edge v1, which honored the configured health check host.

Change Type

/kind fix

Changelog

Fixed a bug where a BackendConfigPolicy health check host (HTTP host or gRPC authority) was ignored for Static backends because the endpoint-level hostname overrode it, causing health checks to use the wrong Host header.

Additional Notes

Tests added:

  • Unit tests in backendconfigpolicy/plugin_test.go covering HTTP host override, gRPC authority override, and the no-host default-preserved case.
  • A gateway translator golden test (backendconfigpolicy/healthcheck-static-backend.yaml) reproducing the exact issue scenario (Static DNS backend + BackendConfigPolicy with healthCheck.http.host).

The static backend plugin stamps each endpoint's
health_check_config.hostname with the backend's dial address. Per Envoy
semantics, that endpoint-level hostname overrides the cluster-level
http_health_check host, so an explicitly configured
BackendConfigPolicy.healthCheck.http.host was silently ignored and
health checks used the wrong Host header (causing 503s against backends
that route on Host, e.g. ALBs).

When a BackendConfigPolicy configures a health check host (HTTP host or
gRPC authority), clear the auto-stamped endpoint hostname so the
configured cluster-level value is used. The default endpoint hostname is
preserved when no host is configured, matching prior behavior.

This restores the Gloo Edge v1 behavior, where the static plugin
overrode the endpoint hostname with the configured health check host.

Signed-off-by: omar <[email protected]>
Copilot AI review requested due to automatic review settings June 8, 2026 15:38

Copilot AI left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Pull request overview

Fixes a regression where BackendConfigPolicy-configured health check host/authority was ignored for Static backends because the static backend plugin stamped an endpoint-level health_check_config.hostname, which (per Envoy behavior) overrides the cluster-level health check host/authority.

Changes:

  • Clear per-endpoint health_check_config.hostname when the policy configures an explicit HTTP host or gRPC authority, allowing the cluster-level config to take effect.
  • Add unit coverage for HTTP host override, gRPC authority override, and preserving the default when no host is configured.
  • Add a gateway translator golden test reproducing the Static DNS backend + BackendConfigPolicy.healthCheck.http.host scenario.

Reviewed changes

Copilot reviewed 5 out of 5 changed files in this pull request and generated no comments.

Show a summary per file
File Description
pkg/kgateway/extensions2/plugins/backendconfigpolicy/plugin.go Clears endpoint-level health check hostname when an explicit cluster-level host/authority is configured.
pkg/kgateway/extensions2/plugins/backendconfigpolicy/plugin_test.go Adds unit tests validating hostname clearing/preservation behavior.
pkg/kgateway/translator/gateway/gateway_translator_test.go Adds a translator golden test case exercising the scenario end-to-end.
pkg/kgateway/translator/gateway/testutils/inputs/backendconfigpolicy/healthcheck-static-backend.yaml New input fixture reproducing the Static backend + policy health check host configuration.
pkg/kgateway/translator/gateway/testutils/outputs/backendconfigpolicy/healthcheck-static-backend.yaml New expected output ensuring cluster-level host is set and endpoint health check hostname override is removed.

@puertomontt
puertomontt enabled auto-merge June 8, 2026 15:48

@sheidkamp sheidkamp left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

One small update to the tests - otherwise lgtm

cluster := clusterWithEndpointHealthCheckHostname(dialHost)
processBackend(context.Background(), policyIR, ir.BackendObjectIR{}, cluster)

assert.Empty(t, endpointHealthCheckHostname(cluster), "endpoint hostname should be cleared so the configured authority wins")

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The HTTP test also checks the healthcheck host. Should we do the same here?

@puertomontt
puertomontt added this pull request to the merge queue Jun 23, 2026
@github-merge-queue
github-merge-queue Bot removed this pull request from the merge queue due to failed status checks Jun 23, 2026
@puertomontt
puertomontt added this pull request to the merge queue Jun 23, 2026
Merged via the queue into kgateway-dev:main with commit 717f794 Jun 23, 2026
34 of 37 checks passed
@puertomontt
puertomontt deleted the fix/static-backend-healthcheck-host-override branch June 23, 2026 14:43
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

kind/fix Categorizes issue or PR as related to a bug. release-note

Projects

None yet

Development

Successfully merging this pull request may close these issues.

4 participants