Description
When a BackendTrafficPolicy in Envoy Gateway v1.8.0-rc.1 is updated to reference a nonexistent HTTPRoute, the policy status does not clearly report the invalid attachment.
Instead:
- the policy continues to show
Accepted=True
- no condition indicates that the target route is missing / unresolved
status.ancestors[*].conditions[*].observedGeneration remains stale and does not match the latest metadata.generation
This makes it hard to tell from status whether the policy is actually attached to a valid target.
Reproducer
- Create a kind cluster
- Install Envoy Gateway
v1.8.0-rc.1
- Apply the quickstart example
- Create a valid
BackendTrafficPolicy targeting the quickstart HTTPRoute
- Update the policy so
targetRefs.name points to a nonexistent route
Environment
- Envoy Gateway version:
v1.8.0-rc.1
- Install method: Helm chart
oci://docker.io/envoyproxy/gateway-helm
- Gateway image:
docker.io/envoyproxy/gateway:v1.8.0-rc.1
Initial valid policy
apiVersion: gateway.envoyproxy.io/v1alpha1
kind: BackendTrafficPolicy
metadata:
name: quickstart-btp
namespace: default
spec:
targetRefs:
- group: gateway.networking.k8s.io
kind: HTTPRoute
name: backend
retry:
numRetries: 3
perRetry:
backOff:
baseInterval: 100ms
maxInterval: 1s
timeout: 250ms
retryOn:
triggers:
- 5xx
- gateway-error
- connect-failure
Updated invalid policy
apiVersion: gateway.envoyproxy.io/v1alpha1
kind: BackendTrafficPolicy
metadata:
name: quickstart-btp
namespace: default
spec:
targetRefs:
- group: gateway.networking.k8s.io
kind: HTTPRoute
name: does-not-exist
retry:
numRetries: 3
perRetry:
backOff:
baseInterval: 100ms
maxInterval: 1s
timeout: 250ms
retryOn:
triggers:
- 5xx
- gateway-error
- connect-failure
Observed behavior
The target route does not exist:
kubectl -n default get httproute does-not-exist
# Error from server (NotFound): httproutes.gateway.networking.k8s.io "does-not-exist" not found
But the policy status remains:
status:
ancestors:
- ancestorRef:
group: gateway.networking.k8s.io
kind: Gateway
name: eg
namespace: default
conditions:
- type: Accepted
status: "True"
reason: Accepted
message: Policy has been accepted.
observedGeneration: 3
while:
So:
Accepted=True is still reported
- no condition indicates unresolved or missing target
observedGeneration is stale (3 vs current generation 4)
Expected behavior
I’d expect one of the following:
- a condition indicating the referenced target does not exist / cannot be resolved
- attachment status that clearly shows the policy is not applied to any valid target
observedGeneration updated to the latest generation even if attachment fails
At minimum, status should make it obvious that the policy is not effectively attached.
Why this matters
From the user perspective, the current status is misleading:
- the object is syntactically valid, so
Accepted=True makes sense at one level
- but there is no visible status signal that the targetRef is broken
- stale
observedGeneration adds more ambiguity about whether reconciliation completed
This makes debugging policy attachment failures much harder.
I believe this also happens to other xPolicies and Gateway API resources.
Description
When a
BackendTrafficPolicyin Envoy Gatewayv1.8.0-rc.1is updated to reference a nonexistentHTTPRoute, the policy status does not clearly report the invalid attachment.Instead:
Accepted=Truestatus.ancestors[*].conditions[*].observedGenerationremains stale and does not match the latestmetadata.generationThis makes it hard to tell from status whether the policy is actually attached to a valid target.
Reproducer
v1.8.0-rc.1BackendTrafficPolicytargeting the quickstartHTTPRoutetargetRefs.namepoints to a nonexistent routeEnvironment
v1.8.0-rc.1oci://docker.io/envoyproxy/gateway-helmdocker.io/envoyproxy/gateway:v1.8.0-rc.1Initial valid policy
Updated invalid policy
Observed behavior
The target route does not exist:
kubectl -n default get httproute does-not-exist # Error from server (NotFound): httproutes.gateway.networking.k8s.io "does-not-exist" not foundBut the policy status remains:
while:
So:
Accepted=Trueis still reportedobservedGenerationis stale (3vs current generation4)Expected behavior
I’d expect one of the following:
observedGenerationupdated to the latest generation even if attachment failsAt minimum, status should make it obvious that the policy is not effectively attached.
Why this matters
From the user perspective, the current status is misleading:
Accepted=Truemakes sense at one levelobservedGenerationadds more ambiguity about whether reconciliation completedThis makes debugging policy attachment failures much harder.
I believe this also happens to other xPolicies and Gateway API resources.