Repository: envoyproxy/gateway

Issue:
problem with all routes 404 when using incorrect filters
> Same problem with all routes 404 when using filters
> ```
> ---
> apiVersion: gateway.networking.k8s.io/v1
> kind: HTTPRoute
> metadata:
>   name: something
> spec:
>   parentRefs:
>     - name: eg
>       namespace: something
>       sectionName: something
>   hostnames:
>     - something.com
>   rules:
>     - backendRefs:
>         - group: ""
>           kind: Service
>           name: something
>           port: 123
>           weight: 1
>       filters:
>         - type: RequestHeaderModifier
>           requestHeaderModifier:
>             add:
>               - name: Host
>                 value: something.com
>               - name: X-Forwarded-Proto
>                 value: https
>               - name: X-Forwarded-Host
>                 value: something.com
>       matches:
>         - path:
>             type: PathPrefix
>             value: /
> ```
> I understand that filters are not needed here and maybe they are written incorrectly, I'm just making a report that the problem in one httproute affects all httroutes in the cluster.
>  

 _Originally posted by @dda104 in [#5147](https://github.com/envoyproxy/gateway/issues/5147#issuecomment-2626491121)_

Discussion:
@surenraju: Currently, in `snapshotcache.go` (line 332), when Envoy rejects an xDS update, we log it at DEBUG level:

https://github.com/envoyproxy/gateway/blob/main/internal/xds/cache/snapshotcache.go#L332

```go
if status := req.ErrorDetail; status != nil {
    // if Envoy rejected the last update log the details here.
    // TODO(youngnick): Handle NACK properly
    errorCode = status.Code
    errorMessage = status.Message
}
s.log.Debugf("handling v3 xDS resource request, response_nonce %s, nodeID %s, node_version %s, resource_names_subscribe %v, resource_names_unsubscribe %v, type_url %s, errorCode %d, errorMessage %s",
    req.ResponseNonce,
    nodeID, nodeVersion,
    req.ResourceNamesSubscribe, req.ResourceNamesUnsubscribe,
    req.GetTypeUrl(),
    errorCode, errorMessage)
```
We should log this as an error `s.log.Errorf` instead of `Debugf`, since a failed xDS update might indicate a critical configuration issue.@zhaohuabing: @dda104 I can't reproduce the reported issue with the HTTPRoute that you pasted in EG 1.3.0. Did I miss anything?@vmcdxliii: @zhaohuabing try create new httproutes after one incorrect. In my case they returns 404. Also try restart k8s cluster and check httproutes.@surenraju: The issue is reproducible. You need to apply first incorrect and the correct configurations, or you can also restart the proxy pod@zhaohuabing: This is because the RouteConfiguration was rejected by envoy: `Envoy rejected the last update with code 13 and message :-prefixed or host headers may not be modified`

It's not a proto validation but a validation in [Envoy source code](https://github.com/envoyproxy/envoy/blob/53941d96922ae2bee829863929fc127921e167b3/source/common/router/header_parser.cc#L27-L39), so EG can't catch it.@arkodg: We could add a CEL validation upstream to not allow Host header to be modified via this filter and to use Url rewrite instead 

Solution patch:
diff --git a/README.md b/README.md
index 66026d003..6401dcca6 100644
--- a/README.md
+++ b/README.md
@@ -19,6 +19,7 @@ Kubernetes-based application gateway.
 * [Goals](GOALS.md)
 * [Quickstart](https://gateway.envoyproxy.io/latest/tasks/quickstart/) to use Envoy Gateway in a few simple steps.
 * [Roadmap](https://gateway.envoyproxy.io/contributions/roadmap/)
+* [Compatibility Matrix](https://gateway.envoyproxy.io/news/releases/matrix/)
 
 ## Contact
 
diff --git a/examples/extension-server/go.mod b/examples/extension-server/go.mod
index 97e9cf38f..8d660018c 100644
--- a/examples/extension-server/go.mod
+++ b/examples/extension-server/go.mod
@@ -9,7 +9,7 @@ require (
 	github.com/urfave/cli/v2 v2.27.6
 	google.golang.org/grpc v1.71.0
 	google.golang.org/protobuf v1.36.5
-	k8s.io/apimachinery v0.33.0-alpha.3
+	k8s.io/apimachinery v0.33.0-beta.0
 	sigs.k8s.io/controller-runtime v0.20.3
 	sigs.k8s.io/gateway-api v1.2.1
 )
@@ -24,7 +24,6 @@ require (
 	github.com/go-logr/logr v1.4.2 // indirect
 	github.com/gobuffalo/flect v1.0.3 // indirect
 	github.com/gogo/protobuf v1.3.2 // indirect
-	github.com/google/gofuzz v1.2.0 // indirect
 	github.com/inconshreveable/mousetrap v1.1.0 // indirect
 	github.com/json-iterator/go v1.1.12 // indirect
 	github.com/mattn/go-colorable v0.1.14 // indirect
@@ -48,13 +47,14 @@ require (
 	gopkg.in/inf.v0 v0.9.1 // indirect
 	gopkg.in/yaml.v2 v2.4.0 // indirect
 	gopkg.in/yaml.v3 v3.0.1 // indirect
-	k8s.io/api v0.32.2 // indirect
-	k8s.io/apiextensions-apiserver v0.32.2 // indirect
+	k8s.io/api v0.32.3 // indirect
+	k8s.io/apiextensions-apiserver v0.32.3 // indirect
 	k8s.io/klog/v2 v2.130.1 // indirect
 	k8s.io/utils v0.0.0-20241210054802-24370beab758 // indirect
 	sigs.k8s.io/controller-tools v0.17.1 // indirect
 	sigs.k8s.io/json v0.0.0-20241014173422-cfa47c3a1cc8 // indirect
-	sigs.k8s.io/structured-merge-diff/v4 v4.5.0 // indirect
+	sigs.k8s.io/randfill v1.0.0 // indirect
+	sigs.k8s.io/structured-merge-diff/v4 v4.6.0 // indirect
 	sigs.k8s.io/yaml v1.4.0 // indirect
 )
 
diff --git a/examples/extension-server/go.sum b/examples/extension-server/go.sum
index ce4e52cb8..3fe8999a4 100644
--- a/examples/extension-server/go.sum
+++ b/examples/extension-server/go.sum
@@ -36,8 +36,6 @@ github.com/google/go-cmp v0.5.9/go.mod h1:17dUlkBOakJ0+DkrSSNjCkIjxS6bF9zb3elmeN
 github.com/google/go-cmp v0.7.0 h1:wk8382ETsv4JYUZwIsn6YpYiWiBsYLSJiTsyBybVuN8=
 github.com/google/go-cmp v0.7.0/go.mod h1:pXiqmnSA92OHEEa9HXL2W4E7lf9JzCmGVUdgjX3N/iU=
 github.com/google/gofuzz v1.0.0/go.mod h1:dBl0BpW6vV/+mYPU4Po3pmUjxk6FQPldtuIdl/M65Eg=
-github.com/google/gofuzz v1.2.0 h1:xRy4A+RhZaiKjJ1bPfwQ8sedCA+YS2YcCHW6ec7JMi0=
-github.com/google/gofuzz v1.2.0/go.mod h1:dBl0BpW6vV/+mYPU4Po3pmUjxk6FQPldtuIdl/M65Eg=
 github.com/google/pprof v0.0.0-20241210010833-40e02aabc2ad h1:a6HEuzUHeKH6hwfN/ZoQgRgVIWFJljSWa/zetS2WTvg=
 github.com/google/pprof v0.0.0-20241210010833-40e02aabc2ad/go.mod h1:vavhavw2zAxS5dIdcRluK6cSGGPlZynqzFM8NdvU144=
 github.com/google/uuid v1.6.0 h1:NIvaJDMOsjHA8n1jAhLSgzrAzy1Hgr+hNrb57e+94F0=
@@ -169,12 +167,12 @@ gopkg.in/yaml.v2 v2.4.0/go.mod h1:RDklbk79AGWmwhnvt/jBztapEOGDOx6ZbXqjP6csGnQ=
 gopkg.in/yaml.v3 v3.0.0-20200313102051-9f266ea9e77c/go.mod h1:K4uyk7z7BCEPqu6E+C64Yfv1cQ7kz7rIZviUmN+EgEM=
 gopkg.in/yaml.v3 v3.0.1 h1:fxVm/GzAzEWqLHuvctI91KS9hhNmmWOoWu0XTYJS7CA=
 gopkg.in/yaml.v3 v3.0.1/go.mod h1:K4uyk7z7BCEPqu6E+C64Yfv1cQ7kz7rIZviUmN+EgEM=
-k8s.io/api v0.32.2 h1:bZrMLEkgizC24G9eViHGOPbW+aRo9duEISRIJKfdJuw=
-k8s.io/api v0.32.2/go.mod h1:hKlhk4x1sJyYnHENsrdCWw31FEmCijNGPJO5WzHiJ6Y=
-k8s.io/apiextensions-apiserver v0.32.2 h1:2YMk285jWMk2188V2AERy5yDwBYrjgWYggscghPCvV4=
-k8s.io/apiextensions-apiserver v0.32.2/go.mod h1:GPwf8sph7YlJT3H6aKUWtd0E+oyShk/YHWQHf/OOgCA=
-k8s.io/apimachinery v0.33.0-alpha.3 h1:ugia3DzNbmhUP4mMUBhelThVifqQvB6YqrXz9Ncoans=
-k8s.io/apimachinery v0.33.0-alpha.3/go.mod h1:0rVRgdlgja0MQ+SYCognm5pRNteQOvhHAsDpKOs48GU=
+k8s.io/api v0.32.3 h1:Hw7KqxRusq+6QSplE3NYG4MBxZw1BZnq4aP4cJVINls=
+k8s.io/api v0.32.3/go.mod h1:2wEDTXADtm/HA7CCMD8D8bK4yuBUptzaRhYcYEEYA3k=
+k8s.io/apiextensions-apiserver v0.32.3 h1:4D8vy+9GWerlErCwVIbcQjsWunF9SUGNu7O7hiQTyPY=
+k8s.io/apiextensions-apiserver v0.32.3/go.mod h1:8YwcvVRMVzw0r1Stc7XfGAzB/SIVLunqApySV5V7Dss=
+k8s.io/apimachinery v0.33.0-beta.0 h1:vLDBChfQwyimk6AbuT7OZOIqxSg/44JlXuxqBk85j68=
+k8s.io/apimachinery v0.33.0-beta.0/go.mod h1:S2OIkExGqJOXYSYcAJwQ9zWcc6BkBUdTJUu4M7z0cvo=
 k8s.io/klog/v2 v2.130.1 h1:n9Xl7H1Xvksem4KFG4PYbdQCQxqc/tTUyrgXaOhHSzk=
 k8s.io/klog/v2 v2.130.1/go.mod h1:3Jpz1GvMt720eyJH1ckRHK1EDfpxISzJ7I9OYgaDtPE=
 k8s.io/utils v0.0.0-20241210054802-24370beab758 h1:sdbE21q2nlQtFh65saZY+rRM6x6aJJI8IUa1AmH/qa0=
@@ -187,7 +185,10 @@ sigs.k8s.io/gateway-api v1.2.1 h1:fZZ/+RyRb+Y5tGkwxFKuYuSRQHu9dZtbjenblleOLHM=
 sigs.k8s.io/gateway-api v1.2.1/go.mod h1:EpNfEXNjiYfUJypf0eZ0P5iXA9ekSGWaS1WgPaM42X0=
 sigs.k8s.io/json v0.0.0-20241014173422-cfa47c3a1cc8 h1:gBQPwqORJ8d8/YNZWEjoZs7npUVDpVXUUOFfW6CgAqE=
 sigs.k8s.io/json v0.0.0-20241014173422-cfa47c3a1cc8/go.mod h1:mdzfpAEoE6DHQEN0uh9ZbOCuHbLK5wOm7dK4ctXE9Tg=
-sigs.k8s.io/structured-merge-diff/v4 v4.5.0 h1:nbCitCK2hfnhyiKo6uf2HxUPTCodY6Qaf85SbDIaMBk=
-sigs.k8s.io/structured-merge-diff/v4 v4.5.0/go.mod h1:N8f93tFZh9U6vpxwRArLiikrE5/2tiu1w1AGfACIGE4=
+sigs.k8s.io/randfill v0.0.0-20250304075658-069ef1bbf016/go.mod h1:XeLlZ/jmk4i1HRopwe7/aU3H5n1zNUcX6TM94b3QxOY=
+sigs.k8s.io/randfill v1.0.0 h1:JfjMILfT8A6RbawdsK2JXGBR5AQVfd+9TbzrlneTyrU=
+sigs.k8s.io/randfill v1.0.0/go.mod h1:XeLlZ/jmk4i1HRopwe7/aU3H5n1zNUcX6TM94b3QxOY=
+sigs.k8s.io/structured-merge-diff/v4 v4.6.0 h1:IUA9nvMmnKWcj5jl84xn+T5MnlZKThmUW1TdblaLVAc=
+sigs.k8s.io/structured-merge-diff/v4 v4.6.0/go.mod h1:dDy58f92j70zLsuZVuUX5Wp9vtxXpaZnkPGWeqDfCps=
 sigs.k8s.io/yaml v1.4.0 h1:Mk1wCc2gy/F0THH0TAp1QYyJNzRm2KCLy3o5ASXVI5E=
 sigs.k8s.io/yaml v1.4.0/go.mod h1:Ejl7/uTz7PSA4eKMyQCUTnhZYNmLIl+5c2lQPGR2BPY=
diff --git a/go.mod b/go.mod
index 3c2370e2f..0d79d1adb 100644
--- a/go.mod
+++ b/go.mod
@@ -46,7 +46,7 @@ require (
 	github.com/spf13/pflag v1.0.6
 	github.com/stretchr/testify v1.10.0
 	github.com/telepresenceio/watchable v0.0.0-20220726211108-9bb86f92afa7
-	github.com/tetratelabs/func-e v1.1.5-0.20240822223546-c85a098d5bf0
+	github.com/tetratelabs/func-e v1.1.5-0.20250319211008-ca8702e12788
 	github.com/tsaarni/certyaml v0.10.0
 	github.com/yuin/gopher-lua v1.1.1
 	go.opentelemetry.io/otel v1.35.0
@@ -66,14 +66,14 @@ require (
 	google.golang.org/protobuf v1.36.5
 	gopkg.in/yaml.v3 v3.0.1
 	helm.sh/helm/v3 v3.17.2
-	k8s.io/api v0.32.2
-	k8s.io/apiextensions-apiserver v0.32.2
-	k8s.io/apimachinery v0.33.0-alpha.3
-	k8s.io/cli-runtime v0.32.2
-	k8s.io/client-go v0.32.2
+	k8s.io/api v0.32.3
+	k8s.io/apiextensions-apiserver v0.32.3
+	k8s.io/apimachinery v0.33.0-beta.0
+	k8s.io/cli-runtime v0.32.3
+	k8s.io/client-go v0.32.3
 	k8s.io/klog/v2 v2.130.1
-	k8s.io/kube-openapi v0.0.0-20241212222426-2c72e554b1e7
-	k8s.io/kubectl v0.32.2
+	k8s.io/kube-openapi v0.0.0-20250304201544-e5f78fe3ede9
+	k8s.io/kubectl v0.32.3
 	k8s.io/utils v0.0.0-20241210054802-24370beab758
 	sigs.k8s.io/controller-runtime v0.20.3
 	sigs.k8s.io/gateway-api v1.2.1
@@ -161,7 +161,7 @@ require (
 	github.com/cilium/ebpf v0.17.3 // indirect
 	github.com/ckaznocha/intrange v0.3.0 // indirect
 	github.com/containerd/cgroups/v3 v3.0.5 // indirect
-	github.com/containerd/containerd v1.7.25 // indirect
+	github.com/containerd/containerd v1.7.27 // indirect
 	github.com/containerd/continuity v0.4.5 // indirect
 	github.com/containerd/errdefs v1.0.0 // indirect
 	github.com/containerd/errdefs/pkg v0.3.0 // indirect
@@ -487,9 +487,9 @@ require (
 	gopkg.in/ini.v1 v1.67.0 // indirect
 	gopkg.in/yaml.v2 v2.4.0 // indirect
 	honnef.co/go/tools v0.6.0 // indirect
-	k8s.io/apiserver v0.32.2 // indirect
-	k8s.io/component-base v0.32.2 // indirect
-	k8s.io/metrics v0.32.2 // indirect
+	k8s.io/apiserver v0.32.3 // indirect
+	k8s.io/component-base v0.32.3 // indirect
+	k8s.io/metrics v0.32.3 // indirect
 	mvdan.cc/gofumpt v0.7.0 // indirect
 	mvdan.cc/unparam v0.0.0-20240528143540-8a5130ca722f // indirect
 	oras.land/oras-go v1.2.6 // indirect
@@ -502,7 +502,8 @@ require (
 	sigs.k8s.io/kind v0.27.0 // indirect
 	sigs.k8s.io/kustomize/api v0.18.0 // indirect
 	sigs.k8s.io/kustomize/kyaml v0.18.1 // indirect
-	sigs.k8s.io/structured-merge-diff/v4 v4.5.0 // indirect
+	sigs.k8s.io/randfill v1.0.0 // indirect
+	sigs.k8s.io/structured-merge-diff/v4 v4.6.0 // indirect
 )
 
 tool (
diff --git a/go.sum b/go.sum
index 8706b5cda..fb2bd2fe4 100644
--- a/go.sum
+++ b/go.sum
@@ -241,8 +241,8 @@ github.com/cncf/xds/go v0.0.0-20241223141626-cff3c89139a3/go.mod h1:W+zGtBO5Y1Ig
 github.com/cockroachdb/datadriven v0.0.0-20190809214429-80d97fb3cbaa/go.mod h1:zn76sxSg3SzpJ0PPJaLDCu+Bu0Lg3sKTORVIj19EIF8=
 github.com/containerd/cgroups/v3 v3.0.5 h1:44na7Ud+VwyE7LIoJ8JTNQOa549a8543BmzaJHo6Bzo=
 github.com/containerd/cgroups/v3 v3.0.5/go.mod h1:SA5DLYnXO8pTGYiAHXz94qvLQTKfVM5GEVisn4jpins=
-github.com/containerd/containerd v1.7.25 h1:khEQOAXOEJalRO228yzVsuASLH42vT7DIo9Ss+9SMFQ=
-github.com/containerd/containerd v1.7.25/go.mod h1:tWfHzVI0azhw4CT2vaIjsb2CoV4LJ9PrMPaULAr21Ok=
+github.com/containerd/containerd v1.7.27 h1:yFyEyojddO3MIGVER2xJLWoCIn+Up4GaHFquP7hsFII=
+github.com/containerd/containerd v1.7.27/go.mod h1:xZmPnl75Vc+BLGt4MIfu6bp+fy03gdHAn9bz+FreFR0=
 github.com/containerd/continuity v0.4.5 h1:ZRoN1sXq9u7V6QoHMcVWGhOwDFqZ4B9i5H6un1Wh0x4=
 github.com/containerd/continuity v0.4.5/go.mod h1:/lNJvtJKUQStBzpVQ1+rasXO1LAWtUQssk28EZvJ3nE=
 github.com/containerd/errdefs v1.0.0 h1:tg5yIfIlQIrxYtu9ajqY42W3lpS19XqdxRQeEwYG8PI=
@@ -1226,8 +1226,8 @@ github.com/tenntenn/text/transform v0.0.0-20200319021203-7eef512accb3 h1:f+jULpR
 github.com/tenntenn/text/transform v0.0.0-20200319021203-7eef512accb3/go.mod h1:ON8b8w4BN/kE1EOhwT0o+d62W65a6aPw1nouo9LMgyY=
 github.com/tetafro/godot v1.4.20 h1:z/p8Ek55UdNvzt4TFn2zx2KscpW4rWqcnUrdmvWJj7E=
 github.com/tetafro/godot v1.4.20/go.mod h1:2oVxTBSftRTh4+MVfUaUXR6bn2GDXCaMcOG4Dk3rfio=
-github.com/tetratelabs/func-e v1.1.5-0.20240822223546-c85a098d5bf0 h1:+OHaiOveLnsmUMSZT5vxL6rrpy5rcSsfnx9Mogfo1Kk=
-github.com/tetratelabs/func-e v1.1.5-0.20240822223546-c85a098d5bf0/go.mod h1:u78wX1mT5MiSZ3rw8+epQ7fcIT7m83YiwdPT2EWgb0Y=
+github.com/tetratelabs/func-e v1.1.5-0.20250319211008-ca8702e12788 h1:hgrf9mjrDENx+A5b5O03qqww7EknhRR0D9TQ0PX9LoU=
+github.com/tetratelabs/func-e v1.1.5-0.20250319211008-ca8702e12788/go.mod h1:FDAoUIMZc6Jkc0oEsbd2aTWRQhWDVrKhKy+yAdMfZbg=
 github.com/tetratelabs/wazero v1.8.2 h1:yIgLR/b2bN31bjxwXHD8a3d+BogigR952csSDdLYEv4=
 github.com/tetratelabs/wazero v1.8.2/go.mod h1:yAI0XTsMBhREkM/YDAK/zNou3GoiAce1P6+rp/wQhjs=
 github.com/tidwall/pretty v1.0.0/go.mod h1:XNkn88O1ChpSDQmQeStsy+sBenx6DDtFZJxhVysOjyk=
@@ -1730,32 +1730,32 @@ honnef.co/go/tools v0.6.0 h1:TAODvD3knlq75WCp2nyGJtT4LeRV/o7NN9nYPeVJXf8=
 honnef.co/go/tools v0.6.0/go.mod h1:3puzxxljPCe8RGJX7BIy1plGbxEOZni5mR2aXe3/uk4=
 k8s.io/api v0.18.2/go.mod h1:SJCWI7OLzhZSvbY7U8zwNl9UA4o1fizoug34OV/2r78=
 k8s.io/api v0.18.4/go.mod h1:lOIQAKYgai1+vz9J7YcDZwC26Z0zQewYOGWdyIPUUQ4=
-k8s.io/api v0.32.2 h1:bZrMLEkgizC24G9eViHGOPbW+aRo9duEISRIJKfdJuw=
-k8s.io/api v0.32.2/go.mod h1:hKlhk4x1sJyYnHENsrdCWw31FEmCijNGPJO5WzHiJ6Y=
+k8s.io/api v0.32.3 h1:Hw7KqxRusq+6QSplE3NYG4MBxZw1BZnq4aP4cJVINls=
+k8s.io/api v0.32.3/go.mod h1:2wEDTXADtm/HA7CCMD8D8bK4yuBUptzaRhYcYEEYA3k=
 k8s.io/apiextensions-apiserver v0.18.2/go.mod h1:q3faSnRGmYimiocj6cHQ1I3WpLqmDgJFlKL37fC4ZvY=
 k8s.io/apiextensions-apiserver v0.18.4/go.mod h1:NYeyeYq4SIpFlPxSAB6jHPIdvu3hL0pc36wuRChybio=
-k8s.io/apiextensions-apiserver v0.32.2 h1:2YMk285jWMk2188V2AERy5yDwBYrjgWYggscghPCvV4=
-k8s.io/apiextensions-apiserver v0.32.2/go.mod h1:GPwf8sph7YlJT3H6aKUWtd0E+oyShk/YHWQHf/OOgCA=
+k8s.io/apiextensions-apiserver v0.32.3 h1:4D8vy+9GWerlErCwVIbcQjsWunF9SUGNu7O7hiQTyPY=
+k8s.io/apiextensions-apiserver v0.32.3/go.mod h1:8YwcvVRMVzw0r1Stc7XfGAzB/SIVLunqApySV5V7Dss=
 k8s.io/apimachinery v0.18.2/go.mod h1:9SnR/e11v5IbyPCGbvJViimtJ0SwHG4nfZFjU77ftcA=
 k8s.io/apimachinery v0.18.4/go.mod h1:OaXp26zu/5J7p0f92ASynJa1pZo06YlV9fG7BoWbCko=
-k8s.io/apimachinery v0.33.0-alpha.3 h1:ugia3DzNbmhUP4mMUBhelThVifqQvB6YqrXz9Ncoans=
-k8s.io/apimachinery v0.33.0-alpha.3/go.mod h1:0rVRgdlgja0MQ+SYCognm5pRNteQOvhHAsDpKOs48GU=
+k8s.io/apimachinery v0.33.0-beta.0 h1:vLDBChfQwyimk6AbuT7OZOIqxSg/44JlXuxqBk85j68=
+k8s.io/apimachinery v0.33.0-beta.0/go.mod h1:S2OIkExGqJOXYSYcAJwQ9zWcc6BkBUdTJUu4M7z0cvo=
 k8s.io/apiserver v0.18.2/go.mod h1:Xbh066NqrZO8cbsoenCwyDJ1OSi8Ag8I2lezeHxzwzw=
 k8s.io/apiserver v0.18.4/go.mod h1:q+zoFct5ABNnYkGIaGQ3bcbUNdmPyOCoEBcg51LChY8=
-k8s.io/apiserver v0.32.2 h1:WzyxAu4mvLkQxwD9hGa4ZfExo3yZZaYzoYvvVDlM6vw=
-k8s.io/apiserver v0.32.2/go.mod h1:PEwREHiHNU2oFdte7BjzA1ZyjWjuckORLIK/wLV5goM=
-k8s.io/cli-runtime v0.32.2 h1:aKQR4foh9qeyckKRkNXUccP9moxzffyndZAvr+IXMks=
-k8s.io/cli-runtime v0.32.2/go.mod h1:a/JpeMztz3xDa7GCyyShcwe55p8pbcCVQxvqZnIwXN8=
+k8s.io/apiserver v0.32.3 h1:kOw2KBuHOA+wetX1MkmrxgBr648ksz653j26ESuWNY8=
+k8s.io/apiserver v0.32.3/go.mod h1:q1x9B8E/WzShF49wh3ADOh6muSfpmFL0I2t+TG0Zdgc=
+k8s.io/cli-runtime v0.32.3 h1:khLF2ivU2T6Q77H97atx3REY9tXiA3OLOjWJxUrdvss=
+k8s.io/cli-runtime v0.32.3/go.mod h1:vZT6dZq7mZAca53rwUfdFSZjdtLyfF61mkf/8q+Xjak=
 k8s.io/client-go v0.18.2/go.mod h1:Xcm5wVGXX9HAA2JJ2sSBUn3tCJ+4SVlCbl2MNNv+CIU=
 k8s.io/client-go v0.18.4/go.mod h1:f5sXwL4yAZRkAtzOxRWUhA/N8XzGCb+nPZI8PfobZ9g=
-k8s.io/client-go v0.32.2 h1:4dYCD4Nz+9RApM2b/3BtVvBHw54QjMFUl1OLcJG5yOA=
-k8s.io/client-go v0.32.2/go.mod h1:fpZ4oJXclZ3r2nDOv+Ux3XcJutfrwjKTCHz2H3sww94=
+k8s.io/client-go v0.32.3 h1:RKPVltzopkSgHS7aS98QdscAgtgah/+zmpAogooIqVU=
+k8s.io/client-go v0.32.3/go.mod h1:3v0+3k4IcT9bXTc4V2rt+d2ZPPG700Xy6Oi0Gdl2PaY=
 k8s.io/code-generator v0.18.2/go.mod h1:+UHX5rSbxmR8kzS+FAv7um6dtYrZokQvjHpDSYRVkTc=
 k8s.io/code-generator v0.18.4/go.mod h1:TgNEVx9hCyPGpdtCWA34olQYLkh3ok9ar7XfSsr8b6c=
 k8s.io/component-base v0.18.2/go.mod h1:kqLlMuhJNHQ9lz8Z7V5bxUUtjFZnrypArGl58gmDfUM=
 k8s.io/component-base v0.18.4/go.mod h1:7jr/Ef5PGmKwQhyAz/pjByxJbC58mhKAhiaDu0vXfPk=
-k8s.io/component-base v0.32.2 h1:1aUL5Vdmu7qNo4ZsE+569PV5zFatM9hl+lb3dEea2zU=
-k8s.io/component-base v0.32.2/go.mod h1:PXJ61Vx9Lg+P5mS8TLd7bCIr+eMJRQTyXe8KvkrvJq0=
+k8s.io/component-base v0.32.3 h1:98WJvvMs3QZ2LYHBzvltFSeJjEx7t5+8s71P7M74u8k=
+k8s.io/component-base v0.32.3/go.mod h1:LWi9cR+yPAv7cu2X9rZanTiFKB2kHA+JjmhkKjCZRpI=
 k8s.io/gengo v0.0.0-20190128074634-0689ccc1d7d6/go.mod h1:ezvh/TsK7cY6rbqRK0oQQ8IAqLxYwwyPxAX1Pzy0ii0=
 k8s.io/gengo v0.0.0-20200114144118-36b2048a9120/go.mod h1:ezvh/TsK7cY6rbqRK0oQQ8IAqLxYwwyPxAX1Pzy0ii0=
 k8s.io/klog v0.0.0-20181102134211-b9b56d5dfc92/go.mod h1:Gq+BEi5rUBO/HRz0bTSXDUcqjScdoY3a9IHpCEIOOfk=
@@ -1764,16 +1764,16 @@ k8s.io/klog v1.0.0/go.mod h1:4Bi6QPql/J/LkTDqv7R/cd3hPo4k2DG6Ptcz060Ez5I=
 k8s.io/klog/v2 v2.0.0/go.mod h1:PBfzABfn139FHAV07az/IF9Wp1bkk3vpT2XSJ76fSDE=
 k8s.io/klog/v2 v2.130.1 h1:n9Xl7H1Xvksem4KFG4PYbdQCQxqc/tTUyrgXaOhHSzk=
 k8s.io/klog/v2 v2.130.1/go.mod h1:3Jpz1GvMt720eyJH1ckRHK1EDfpxISzJ7I9OYgaDtPE=
-k8s.io/kms v0.32.2 h1:7Ff23ht7W40gTcDwUC8G5WjX5W/nxD8WxbNhIYYNZCI=
-k8s.io/kms v0.32.2/go.mod h1:Bk2evz/Yvk0oVrvm4MvZbgq8BD34Ksxs2SRHn4/UiOM=
+k8s.io/kms v0.32.3 h1:HhHw5+pRCzEJp3oFFJ1q5W2N6gAI7YkUg4ay4Z0dgwM=
+k8s.io/kms v0.32.3/go.mod h1:Bk2evz/Yvk0oVrvm4MvZbgq8BD34Ksxs2SRHn4/UiOM=
 k8s.io/kube-openapi v0.0.0-20200121204235-bf4fb3bd569c/go.mod h1:GRQhZsXIAJ1xR0C9bd8UpWHZ5plfAS9fzPjJuQ6JL3E=
 k8s.io/kube-openapi v0.0.0-20200410145947-61e04a5be9a6/go.mod h1:GRQhZsXIAJ1xR0C9bd8UpWHZ5plfAS9fzPjJuQ6JL3E=
-k8s.io/kube-openapi v0.0.0-20241212222426-2c72e554b1e7 h1:hcha5B1kVACrLujCKLbr8XWMxCxzQx42DY8QKYJrDLg=
-k8s.io/kube-openapi v0.0.0-20241212222426-2c72e554b1e7/go.mod h1:GewRfANuJ70iYzvn+i4lezLDAFzvjxZYK1gn1lWcfas=
-k8s.io/kubectl v0.32.2 h1:TAkag6+XfSBgkqK9I7ZvwtF0WVtUAvK8ZqTt+5zi1Us=
-k8s.io/kubectl v0.32.2/go.mod h1:+h/NQFSPxiDZYX/WZaWw9fwYezGLISP0ud8nQKg+3g8=
-k8s.io/metrics v0.32.2 h1:7t/rZzTHFrGa9f94XcgLlm3ToAuJtdlHANcJEHlYl9g=
-k8s.io/metrics v0.32.2/go.mod h1:VL3nJpzcgB6L5nSljkkzoE0nilZhVgcjCfNRgoylaIQ=
+k8s.io/kube-openapi v0.0.0-20250304201544-e5f78fe3ede9 h1:t0huyHnz6HsokckRxAF1bY0cqPFwzINKCL7yltEjZQc=
+k8s.io/kube-openapi v0.0.0-20250304201544-e5f78fe3ede9/go.mod h1:5jIi+8yX4RIb8wk3XwBo5Pq2ccx4FP10ohkbSKCZoK8=
+k8s.io/kubectl v0.32.3 h1:VMi584rbboso+yjfv0d8uBHwwxbC438LKq+dXd5tOAI=
+k8s.io/kubectl v0.32.3/go.mod h1:6Euv2aso5GKzo/UVMacV6C7miuyevpfI91SvBvV9Zdg=
+k8s.io/metrics v0.32.3 h1:2vsBvw0v8rIIlczZ/lZ8Kcqk9tR6Fks9h+dtFNbc2a4=
+k8s.io/metrics v0.32.3/go.mod h1:9R1Wk5cb+qJpCQon9h52mgkVCcFeYxcY+YkumfwHVCU=
 k8s.io/utils v0.0.0-20200324210504-a9aa75ae1b89/go.mod h1:sZAwmy6armz5eXlNoLmJcl4F1QuKu7sr+mFQ0byX7Ew=
 k8s.io/utils v0.0.0-20200603063816-c1c6865ac451/go.mod h1:jPW/WVKK9YHAvNhRxK0md/EJ228hCsBRufyofKtW8HA=
 k8s.io/utils v0.0.0-20241210054802-24370beab758 h1:sdbE21q2nlQtFh65saZY+rRM6x6aJJI8IUa1AmH/qa0=
@@ -1814,10 +1814,13 @@ sigs.k8s.io/kustomize/kyaml v0.18.1 h1:WvBo56Wzw3fjS+7vBjN6TeivvpbW9GmRaWZ9CIVmt
 sigs.k8s.io/kustomize/kyaml v0.18.1/go.mod h1:C3L2BFVU1jgcddNBE1TxuVLgS46TjObMwW5FT9FcjYo=
 sigs.k8s.io/mcs-api v0.1.0 h1:edDbg0oRGfXw8TmZjKYep06LcJLv/qcYLidejnUp0PM=
 sigs.k8s.io/mcs-api v0.1.0/go.mod h1:gGiAryeFNB4GBsq2LBmVqSgKoobLxt+p7ii/WG5QYYw=
+sigs.k8s.io/randfill v0.0.0-20250304075658-069ef1bbf016/go.mod h1:XeLlZ/jmk4i1HRopwe7/aU3H5n1zNUcX6TM94b3QxOY=
+sigs.k8s.io/randfill v1.0.0 h1:JfjMILfT8A6RbawdsK2JXGBR5AQVfd+9TbzrlneTyrU=
+sigs.k8s.io/randfill v1.0.0/go.mod h1:XeLlZ/jmk4i1HRopwe7/aU3H5n1zNUcX6TM94b3QxOY=
 sigs.k8s.io/structured-merge-diff/v3 v3.0.0-20200116222232-67a7b8c61874/go.mod h1:PlARxl6Hbt/+BC80dRLi1qAmnMqwqDg62YvvVkZjemw=
 sigs.k8s.io/structured-merge-diff/v3 v3.0.0/go.mod h1:PlARxl6Hbt/+BC80dRLi1qAmnMqwqDg62YvvVkZjemw=
-sigs.k8s.io/structured-merge-diff/v4 v4.5.0 h1:nbCitCK2hfnhyiKo6uf2HxUPTCodY6Qaf85SbDIaMBk=
-sigs.k8s.io/structured-merge-diff/v4 v4.5.0/go.mod h1:N8f93tFZh9U6vpxwRArLiikrE5/2tiu1w1AGfACIGE4=
+sigs.k8s.io/structured-merge-diff/v4 v4.6.0 h1:IUA9nvMmnKWcj5jl84xn+T5MnlZKThmUW1TdblaLVAc=
+sigs.k8s.io/structured-merge-diff/v4 v4.6.0/go.mod h1:dDy58f92j70zLsuZVuUX5Wp9vtxXpaZnkPGWeqDfCps=
 sigs.k8s.io/yaml v1.1.0/go.mod h1:UJmg0vDUVViEyp3mgSv9WPwZCDxu4rQW1olrI1uml+o=
 sigs.k8s.io/yaml v1.2.0/go.mod h1:yfXDCHCao9+ENCvLSE62v9VSji2MKu5jeNfTrofGhJc=
 sigs.k8s.io/yaml v1.4.0 h1:Mk1wCc2gy/F0THH0TAp1QYyJNzRm2KCLy3o5ASXVI5E=
diff --git a/internal/cmd/server.go b/internal/cmd/server.go
index 80808a420..99c1856b4 100644
--- a/internal/cmd/server.go
+++ b/internal/cmd/server.go
@@ -31,6 +31,9 @@ import (
 type Runner interface {
 	Start(context.Context) error
 	Name() string
+	// Close closes the runner when the server is shutting down.
+	// This called after all the subscriptions are closed at the very end of the server shutdown.
+	Close() error
 }
 
 // cfgPath is the path to the EnvoyGateway configuration file.
@@ -59,12 +62,14 @@ func server(ctx context.Context, logOut io.Writer) error {
 		return err
 	}
 
+	runnersDone := make(chan struct{})
 	hook := func(c context.Context, cfg *config.Server) error {
-		cfg.Logger.Info("Setup runners")
-		if err := setupRunners(c, cfg); err != nil {
-			cfg.Logger.Error(err, "failed to setup runners")
+		cfg.Logger.Info("Start runners")
+		if err := startRunners(c, cfg); err != nil {
+			cfg.Logger.Error(err, "failed to start runners")
 			return err
 		}
+		runnersDone <- struct{}{}
 		return nil
 	}
 	l := loader.New(cfgPath, cfg, hook)
@@ -81,11 +86,14 @@ func server(ctx context.Context, logOut io.Writer) error {
 		return err
 	}
 
-	// Wait exit signal
+	// Wait for the context to be done, which usually happens the process receives a SIGTERM or SIGINT.
 	<-ctx.Done()
 
 	cfg.Logger.Info("shutting down")
 
+	// Wait for runners to finish.
+	<-runnersDone
+
 	return nil
 }
 
@@ -129,9 +137,12 @@ func getConfigByPath(logOut io.Writer, cfgPath string) (*config.Server, error) {
 	return cfg, nil
 }
 
-// setupRunners starts all the runners required for the Envoy Gateway to
+// startRunners starts all the runners required for the Envoy Gateway to
 // fulfill its tasks.
-func setupRunners(ctx context.Context, cfg *config.Server) (err error) {
+//
+// This will block until the context is done, and returns after synchronously
+// closing all the runners.
+func startRunners(ctx context.Context, cfg *config.Server) (err error) {
 	channels := struct {
 		pResources *message.ProviderResources
 		xdsIR      *message.XdsIR
@@ -248,6 +259,11 @@ func setupRunners(ctx context.Context, cfg *config.Server) (err error) {
 	}
 
 	cfg.Logger.Info("runners are shutting down")
+	for _, r := range runners {
+		if err := r.runner.Close(); err != nil {
+			cfg.Logger.Error(err, "failed to close runner", "name", r.runner.Name())
+		}
+	}
 
 	if extMgr != nil {
 		// Close connections to extension services
diff --git a/internal/gatewayapi/ext_service.go b/internal/gatewayapi/ext_service.go
index 4eecdaa29..c041cdc4e 100644
--- a/internal/gatewayapi/ext_service.go
+++ b/internal/gatewayapi/ext_service.go
@@ -73,6 +73,9 @@ func (t *Translator) translateExtServiceBackendRefs(
 		Name:     destName,
 		Settings: ds,
 	}
+	if validationErr := rs.Validate(); validationErr != nil {
+		return nil, validationErr
+	}
 	return rs, nil
 }
 
diff --git a/internal/gatewayapi/filters.go b/internal/gatewayapi/filters.go
index 02c032d78..85fdfb4e3 100644
--- a/internal/gatewayapi/filters.go
+++ b/internal/gatewayapi/filters.go
@@ -192,15 +192,9 @@ func (t *Translator) processURLRewriteFilter(
 	if filterContext.URLRewrite != nil {
 		if hasMultipleCoreRewrites(rewrite, filterContext.URLRewrite) ||
 			hasConflictingCoreAndExtensionRewrites(rewrite, filterContext.URLRewrite) {
-			routeStatus := GetRouteStatus(filterContext.Route)
-			status.SetRouteStatusCondition(routeStatus,
-				filterContext.ParentRef.routeParentStatusIdx,
-				filterContext.Route.GetGeneration(),
-				gwapiv1.RouteConditionAccepted,
-				metav1.ConditionFalse,
-				gwapiv1.RouteReasonUnsupportedValue,
-				"Cannot configure multiple urlRewrite filters for a single HTTPRouteRule",
-			)
+			updateRouteStatusForFilter(
+				filterContext,
+				"Cannot configure multiple urlRewrite filters for a single HTTPRouteRule")
 			return
 		}
 	}
@@ -213,15 +207,7 @@ func (t *Translator) processURLRewriteFilter(
 
 	if rewrite.Hostname != nil {
 		if err := t.validateHostname(string(*rewrite.Hostname)); err != nil {
-			routeStatus := GetRouteStatus(filterContext.Route)
-			status.SetRouteStatusCondition(routeStatus,
-				filterContext.ParentRef.routeParentStatusIdx,
-				filterContext.Route.GetGeneration(),
-				gwapiv1.RouteConditionAccepted,
-				metav1.ConditionFalse,
-				gwapiv1.RouteReasonUnsupportedValue,
-				err.Error(),
-			)
+			updateRouteStatusForFilter(filterContext, err.Error())
 			return
 		}
 		redirectHost := string(*rewrite.Hostname)
@@ -234,29 +220,15 @@ func (t *Translator) processURLRewriteFilter(
 		switch rewrite.Path.Type {
 		case gwapiv1.FullPathHTTPPathModifier:
 			if rewrite.Path.ReplacePrefixMatch != nil {
-				errMsg := "ReplacePrefixMatch cannot be set when rewrite path type is \"ReplaceFullPath\""
-				routeStatus := GetRouteStatus(filterContext.Route)
-				status.SetRouteStatusCondition(routeStatus,
-					filterContext.ParentRef.routeParentStatusIdx,
-					filterContext.Route.GetGeneration(),
-					gwapiv1.RouteConditionAccepted,
-					metav1.ConditionFalse,
-					gwapiv1.RouteReasonUnsupportedValue,
-					errMsg,
-				)
+				updateRouteStatusForFilter(
+					filterContext,
+					"ReplacePrefixMatch cannot be set when rewrite path type is \"ReplaceFullPath\"")
 				return
 			}
 			if rewrite.Path.ReplaceFullPath == nil {
-				errMsg := "ReplaceFullPath must be set when rewrite path type is \"ReplaceFullPath\""
-				routeStatus := GetRouteStatus(filterContext.Route)
-				status.SetRouteStatusCondition(routeStatus,
-					filterContext.ParentRef.routeParentStatusIdx,
-					filterContext.Route.GetGeneration(),
-					gwapiv1.RouteConditionAccepted,
-					metav1.ConditionFalse,
-					gwapiv1.RouteReasonUnsupportedValue,
-					errMsg,
-				)
+				updateRouteStatusForFilter(
+					filterContext,
+					"ReplaceFullPath must be set when rewrite path type is \"ReplaceFullPath\"")
 				return
 			}
 			if rewrite.Path.ReplaceFullPath != nil {
@@ -268,29 +240,15 @@ func (t *Translator) processURLRewriteFilter(
 			}
 		case gwapiv1.PrefixMatchHTTPPathModifier:
 			if rewrite.Path.ReplaceFullPath != nil {
-				errMsg := "ReplaceFullPath cannot be set when rewrite path type is \"ReplacePrefixMatch\""
-				routeStatus := GetRouteStatus(filterContext.Route)
-				status.SetRouteStatusCondition(routeStatus,
-					filterContext.ParentRef.routeParentStatusIdx,
-					filterContext.Route.GetGeneration(),
-					gwapiv1.RouteConditionAccepted,
-					metav1.ConditionFalse,
-					gwapiv1.RouteReasonUnsupportedValue,
-					errMsg,
-				)
+				updateRouteStatusForFilter(
+					filterContext,
+					"ReplaceFullPath cannot be set when rewrite path type is \"ReplacePrefixMatch\"")
 				return
 			}
 			if rewrite.Path.ReplacePrefixMatch == nil {
-				errMsg := "ReplacePrefixMatch must be set when rewrite path type is \"ReplacePrefixMatch\""
-				routeStatus := GetRouteStatus(filterContext.Route)
-				status.SetRouteStatusCondition(routeStatus,
-					filterContext.ParentRef.routeParentStatusIdx,
-					filterContext.Route.GetGeneration(),
-					gwapiv1.RouteConditionAccepted,
-					metav1.ConditionFalse,
-					gwapiv1.RouteReasonUnsupportedValue,
-					errMsg,
-				)
+				updateRouteStatusForFilter(
+					filterContext,
+					"ReplacePrefixMatch must be set when rewrite path type is \"ReplacePrefixMatch\"")
 				return
 			}
 			if rewrite.Path.ReplacePrefixMatch != nil {
@@ -301,16 +259,11 @@ func (t *Translator) processURLRewriteFilter(
 				}
 			}
 		default:
-			errMsg := fmt.Sprintf("Rewrite path type: %s is invalid, only \"ReplaceFullPath\" and \"ReplacePrefixMatch\" are supported", rewrite.Path.Type)
-			routeStatus := GetRouteStatus(filterContext.Route)
-			status.SetRouteStatusCondition(routeStatus,
-				filterContext.ParentRef.routeParentStatusIdx,
-				filterContext.Route.GetGeneration(),
-				gwapiv1.RouteConditionAccepted,
-				metav1.ConditionFalse,
-				gwapiv1.RouteReasonUnsupportedValue,
-				errMsg,
-			)
+			updateRouteStatusForFilter(
+				filterContext,
+				fmt.Sprintf(
+					"Rewrite path type: %s is invalid, only \"ReplaceFullPath\" and \"ReplacePrefixMatch\" are supported",
+					rewrite.Path.Type))
 			return
 		}
 	}
@@ -324,15 +277,9 @@ func (t *Translator) processRedirectFilter(
 ) {
 	// Can't have two redirects for the same route
 	if filterContext.RedirectResponse != nil {
-		routeStatus := GetRouteStatus(filterContext.Route)
-		status.SetRouteStatusCondition(routeStatus,
-			filterContext.ParentRef.routeParentStatusIdx,
-			filterContext.Route.GetGeneration(),
-			gwapiv1.RouteConditionAccepted,
-			metav1.ConditionFalse,
-			gwapiv1.RouteReasonUnsupportedValue,
-			"Cannot configure multiple requestRedirect filters for a single HTTPRouteRule",
-		)
+		updateRouteStatusForFilter(
+			filterContext,
+			"Cannot configure multiple requestRedirect filters for a single HTTPRouteRule")
 		return
 	}
 
@@ -347,31 +294,16 @@ func (t *Translator) processRedirectFilter(
 		if *redirect.Scheme == "http" || *redirect.Scheme == "https" {
 			redir.Scheme = redirect.Scheme
 		} else {
-			errMsg := fmt.Sprintf("Scheme: %s is unsupported, only 'https' and 'http' are supported", *redirect.Scheme)
-			routeStatus := GetRouteStatus(filterContext.Route)
-			status.SetRouteStatusCondition(routeStatus,
-				filterContext.ParentRef.routeParentStatusIdx,
-				filterContext.Route.GetGeneration(),
-				gwapiv1.RouteConditionAccepted,
-				metav1.ConditionFalse,
-				gwapiv1.RouteReasonUnsupportedValue,
-				errMsg,
-			)
+			updateRouteStatusForFilter(
+				filterContext,
+				fmt.Sprintf("Scheme: %s is unsupported, only 'https' and 'http' are supported", *redirect.Scheme))
 			return
 		}
 	}
 
 	if redirect.Hostname != nil {
 		if err := t.validateHostname(string(*redirect.Hostname)); err != nil {
-			routeStatus := GetRouteStatus(filterContext.Route)
-			status.SetRouteStatusCondition(routeStatus,
-				filterContext.ParentRef.routeParentStatusIdx,
-				filterContext.Route.GetGeneration(),
-				gwapiv1.RouteConditionAccepted,
-				metav1.ConditionFalse,
-				gwapiv1.RouteReasonUnsupportedValue,
-				err.Error(),
-			)
+			updateRouteStatusForFilter(filterContext, err.Error())
 		} else {
 			redirectHost := string(*redirect.Hostname)
 			redir.Hostname = &redirectHost
@@ -393,16 +325,11 @@ func (t *Translator) processRedirectFilter(
 				}
 			}
 		default:
-			errMsg := fmt.Sprintf("Redirect path type: %s is invalid, only \"ReplaceFullPath\" and \"ReplacePrefixMatch\" are supported", redirect.Path.Type)
-			routeStatus := GetRouteStatus(filterContext.Route)
-			status.SetRouteStatusCondition(routeStatus,
-				filterContext.ParentRef.routeParentStatusIdx,
-				filterContext.Route.GetGeneration(),
-				gwapiv1.RouteConditionAccepted,
-				metav1.ConditionFalse,
-				gwapiv1.RouteReasonUnsupportedValue,
-				errMsg,
-			)
+			updateRouteStatusForFilter(
+				filterContext,
+				fmt.Sprintf(
+					"Redirect path type: %s is invalid, only \"ReplaceFullPath\" and \"ReplacePrefixMatch\" are supported",
+					redirect.Path.Type))
 			return
 		}
 	}
@@ -414,15 +341,7 @@ func (t *Translator) processRedirectFilter(
 			redir.StatusCode = &redirectCode
 		} else {
 			errMsg := fmt.Sprintf("Status code %d is invalid, only 302 and 301 are supported", redirectCode)
-			routeStatus := GetRouteStatus(filterContext.Route)
-			status.SetRouteStatusCondition(routeStatus,
-				filterContext.ParentRef.routeParentStatusIdx,
-				filterContext.Route.GetGeneration(),
-				gwapiv1.RouteConditionAccepted,
-				metav1.ConditionFalse,
-				gwapiv1.RouteReasonUnsupportedValue,
-				errMsg,
-			)
+			updateRouteStatusForFilter(filterContext, errMsg)
 			return
 		}
 	}
@@ -453,28 +372,19 @@ func (t *Translator) processRequestHeaderModifierFilter(
 		for _, addHeader := range headersToAdd {
 			emptyFilterConfig = false
 			if addHeader.Name == "" {
-				routeStatus := GetRouteStatus(filterContext.Route)
-				status.SetRouteStatusCondition(routeStatus,
-					filterContext.ParentRef.routeParentStatusIdx,
-					filterContext.Route.GetGeneration(),
-					gwapiv1.RouteConditionAccepted,
-					metav1.ConditionFalse,
-					gwapiv1.RouteReasonUnsupportedValue,
-					"RequestHeaderModifier Filter cannot add a header with an empty name",
-				)
+				updateRouteStatusForFilter(
+					filterContext,
+					"RequestHeaderModifier Filter cannot add a header with an empty name")
 				// try to process the rest of the headers and produce a valid config.
 				continue
 			}
-			// Per Gateway API specification on HTTPHeaderName, : and / are invalid characters in header names
-			if strings.Contains(string(addHeader.Name), "/") || strings.Contains(string(addHeader.Name), ":") {
-				routeStatus := GetRouteStatus(filterContext.Route)
-				status.SetRouteStatusCondition(routeStatus,
-					filterContext.ParentRef.routeParentStatusIdx,
-					filterContext.Route.GetGeneration(),
-					gwapiv1.RouteConditionAccepted,
-					metav1.ConditionFalse,
-					gwapiv1.RouteReasonUnsupportedValue,
-					fmt.Sprintf("RequestHeaderModifier Filter cannot set headers with a '/' or ':' character in them. Header: %q", string(addHeader.Name)),
+			if !isModifiableHeader(string(addHeader.Name)) {
+				updateRouteStatusForFilter(
+					filterContext,
+					fmt.Sprintf(
+						"Header: %q. The RequestHeaderModifier filter cannot set the Host header or headers with a '/' "+
+							"or ':' character in them. To modify the Host header use the URLRewrite or the HTTPRouteFilter filter.",
+						string(addHeader.Name)),
 				)
 				continue
 			}
@@ -510,27 +420,19 @@ func (t *Translator) processRequestHeaderModifierFilter(
 		for _, setHeader := range headersToSet {
 
 			if setHeader.Name == "" {
-				routeStatus := GetRouteStatus(filterContext.Route)
-				status.SetRouteStatusCondition(routeStatus,
-					filterContext.ParentRef.routeParentStatusIdx,
-					filterContext.Route.GetGeneration(),
-					gwapiv1.RouteConditionAccepted,
-					metav1.ConditionFalse,
-					gwapiv1.RouteReasonUnsupportedValue,
-					"RequestHeaderModifier Filter cannot set a header with an empty name",
-				)
+				updateRouteStatusForFilter(
+					filterContext,
+					"RequestHeaderModifier Filter cannot set a header with an empty name")
 				continue
 			}
-			// Per Gateway API specification on HTTPHeaderName, : and / are invalid characters in header names
-			if strings.Contains(string(setHeader.Name), "/") || strings.Contains(string(setHeader.Name), ":") {
-				routeStatus := GetRouteStatus(filterContext.Route)
-				status.SetRouteStatusCondition(routeStatus,
-					filterContext.ParentRef.routeParentStatusIdx,
-					filterContext.Route.GetGeneration(),
-					gwapiv1.RouteConditionAccepted,
-					metav1.ConditionFalse,
-					gwapiv1.RouteReasonUnsupportedValue,
-					fmt.Sprintf("RequestHeaderModifier Filter cannot set headers with a '/' or ':' character in them. Header: '%s'", string(setHeader.Name)),
+
+			if !isModifiableHeader(string(setHeader.Name)) {
+				updateRouteStatusForFilter(
+					filterContext,
+					fmt.Sprintf(
+						"Header: %q. The RequestHeaderModifier filter cannot set the Host header or headers with a '/' "+
+							"or ':' character in them. To modify the Host header use the URLRewrite or the HTTPRouteFilter filter.",
+						string(setHeader.Name)),
 				)
 				continue
 			}
@@ -566,14 +468,19 @@ func (t *Translator) processRequestHeaderModifierFilter(
 		}
 		for _, removedHeader := range headersToRemove {
 			if removedHeader == "" {
-				routeStatus := GetRouteStatus(filterContext.Route)
-				status.SetRouteStatusCondition(routeStatus,
-					filterContext.ParentRef.routeParentStatusIdx,
-					filterContext.Route.GetGeneration(),
-					gwapiv1.RouteConditionAccepted,
-					metav1.ConditionFalse,
-					gwapiv1.RouteReasonUnsupportedValue,
-					"RequestHeaderModifier Filter cannot remove a header with an empty name",
+				updateRouteStatusForFilter(
+					filterContext,
+					"RequestHeaderModifier Filter cannot remove a header with an empty name")
+				continue
+			}
+
+			if !isModifiableHeader(removedHeader) {
+				updateRouteStatusForFilter(
+					filterContext,
+					fmt.Sprintf(
+						"Header: %q. The RequestHeaderModifier filter cannot remove the Host header or headers with a '/' "+
+							"or ':' character in them.",
+						removedHeader),
 				)
 				continue
 			}
@@ -595,18 +502,30 @@ func (t *Translator) processRequestHeaderModifierFilter(
 
 	// Update the status if the filter failed to configure any valid headers to add/remove
 	if len(filterContext.AddRequestHeaders) == 0 && len(filterContext.RemoveRequestHeaders) == 0 && !emptyFilterConfig {
-		routeStatus := GetRouteStatus(filterContext.Route)
-		status.SetRouteStatusCondition(routeStatus,
-			filterContext.ParentRef.routeParentStatusIdx,
-			filterContext.Route.GetGeneration(),
-			gwapiv1.RouteConditionAccepted,
-			metav1.ConditionFalse,
-			gwapiv1.RouteReasonUnsupportedValue,
-			"RequestHeaderModifier Filter did not provide valid configuration to add/set/remove any headers",
-		)
+		updateRouteStatusForFilter(
+			filterContext,
+			"RequestHeaderModifier Filter did not provide valid configuration to add/set/remove any headers")
 	}
 }
 
+func updateRouteStatusForFilter(filterContext *HTTPFiltersContext, message string) {
+	routeStatus := GetRouteStatus(filterContext.Route)
+	status.SetRouteStatusCondition(routeStatus,
+		filterContext.ParentRef.routeParentStatusIdx,
+		filterContext.Route.GetGeneration(),
+		gwapiv1.RouteConditionAccepted,
+		metav1.ConditionFalse,
+		gwapiv1.RouteReasonUnsupportedValue,
+		message,
+	)
+}
+
+func isModifiableHeader(headerName string) bool {
+	// Per Gateway API specification on HTTPHeaderName, : and / are invalid characters in header names
+	// And Envoy does not allow modification the pseudo headers and the host header
+	return !strings.Contains(headerName, "/") && !strings.Contains(headerName, ":") && !strings.EqualFold(headerName, "host")
+}
+
 func (t *Translator) processResponseHeaderModifierFilter(
 	headerModifier *gwapiv1.HTTPHeaderFilter,
 	filterContext *HTTPFiltersContext,
@@ -625,29 +544,19 @@ func (t *Translator) processResponseHeaderModifierFilter(
 		for _, addHeader := range headersToAdd {
 			emptyFilterConfig = false
 			if addHeader.Name == "" {
-				routeStatus := GetRouteStatus(filterContext.Route)
-				status.SetRouteStatusCondition(routeStatus,
-					filterContext.ParentRef.routeParentStatusIdx,
-					filterContext.Route.GetGeneration(),
-					gwapiv1.RouteConditionAccepted,
-					metav1.ConditionFalse,
-					gwapiv1.RouteReasonUnsupportedValue,
-					"ResponseHeaderModifier Filter cannot add a header with an empty name",
-				)
+				updateRouteStatusForFilter(
+					filterContext,
+					"ResponseHeaderModifier Filter cannot add a header with an empty name")
 				// try to process the rest of the headers and produce a valid config.
 				continue
 			}
-			// Per Gateway API specification on HTTPHeaderName, : and / are invalid characters in header names
-			if strings.Contains(string(addHeader.Name), "/") || strings.Contains(string(addHeader.Name), ":") {
-				routeStatus := GetRouteStatus(filterContext.Route)
-				status.SetRouteStatusCondition(routeStatus,
-					filterContext.ParentRef.routeParentStatusIdx,
-					filterContext.Route.GetGeneration(),
-					gwapiv1.RouteConditionAccepted,
-					metav1.ConditionFalse,
-					gwapiv1.RouteReasonUnsupportedValue,
-					fmt.Sprintf("ResponseHeaderModifier Filter cannot set headers with a '/' or ':' character in them. Header: %q", string(addHeader.Name)),
-				)
+			if !isModifiableHeader(string(addHeader.Name)) {
+				updateRouteStatusForFilter(
+					filterContext,
+					fmt.Sprintf(
+						"Header: %q. The ResponseHeaderModifier filter cannot set the Host header or headers with a '/' "+
+							"or ':' character in them.",
+						string(addHeader.Name)))
 				continue
 			}
 			// Check if the header is a duplicate
@@ -682,28 +591,19 @@ func (t *Translator) processResponseHeaderModifierFilter(
 		for _, setHeader := range headersToSet {
 
 			if setHeader.Name == "" {
-				routeStatus := GetRouteStatus(filterContext.Route)
-				status.SetRouteStatusCondition(routeStatus,
-					filterContext.ParentRef.routeParentStatusIdx,
-					filterContext.Route.GetGeneration(),
-					gwapiv1.RouteConditionAccepted,
-					metav1.ConditionFalse,
-					gwapiv1.RouteReasonUnsupportedValue,
-					"ResponseHeaderModifier Filter cannot set a header with an empty name",
-				)
+				updateRouteStatusForFilter(
+					filterContext,
+					"ResponseHeaderModifier Filter cannot set a header with an empty name")
 				continue
 			}
-			// Per Gateway API specification on HTTPHeaderName, : and / are invalid characters in header names
-			if strings.Contains(string(setHeader.Name), "/") || strings.Contains(string(setHeader.Name), ":") {
-				routeStatus := GetRouteStatus(filterContext.Route)
-				status.SetRouteStatusCondition(routeStatus,
-					filterContext.ParentRef.routeParentStatusIdx,
-					filterContext.Route.GetGeneration(),
-					gwapiv1.RouteConditionAccepted,
-					metav1.ConditionFalse,
-					gwapiv1.RouteReasonUnsupportedValue,
-					fmt.Sprintf("ResponseHeaderModifier Filter cannot set headers with a '/' or ':' character in them. Header: '%s'", string(setHeader.Name)),
-				)
+
+			if !isModifiableHeader(string(setHeader.Name)) {
+				updateRouteStatusForFilter(
+					filterContext,
+					fmt.Sprintf(
+						"Header: %q. The ResponseHeaderModifier filter cannot set the Host header or headers with a '/' "+
+							"or ':' character in them.",
+						string(setHeader.Name)))
 				continue
 			}
 
@@ -738,15 +638,18 @@ func (t *Translator) processResponseHeaderModifierFilter(
 		}
 		for _, removedHeader := range headersToRemove {
 			if removedHeader == "" {
-				routeStatus := GetRouteStatus(filterContext.Route)
-				status.SetRouteStatusCondition(routeStatus,
-					filterContext.ParentRef.routeParentStatusIdx,
-					filterContext.Route.GetGeneration(),
-					gwapiv1.RouteConditionAccepted,
-					metav1.ConditionFalse,
-					gwapiv1.RouteReasonUnsupportedValue,
-					"ResponseHeaderModifier Filter cannot remove a header with an empty name",
-				)
+				updateRouteStatusForFilter(
+					filterContext,
+					"ResponseHeaderModifier Filter cannot remove a header with an empty name")
+				continue
+			}
+			if !isModifiableHeader(removedHeader) {
+				updateRouteStatusForFilter(
+					filterContext,
+					fmt.Sprintf(
+						"Header: %q. The ResponseHeaderModifier filter cannot remove the Host header or headers with a '/' "+
+							"or ':' character in them.",
+						removedHeader))
 				continue
 			}
 
@@ -768,15 +671,9 @@ func (t *Translator) processResponseHeaderModifierFilter(
 
 	// Update the status if the filter failed to configure any valid headers to add/remove
 	if len(filterContext.AddResponseHeaders) == 0 && len(filterContext.RemoveResponseHeaders) == 0 && !emptyFilterConfig {
-		routeStatus := GetRouteStatus(filterContext.Route)
-		status.SetRouteStatusCondition(routeStatus,
-			filterContext.ParentRef.routeParentStatusIdx,
-			filterContext.Route.GetGeneration(),
-			gwapiv1.RouteConditionAccepted,
-			metav1.ConditionFalse,
-			gwapiv1.RouteReasonUnsupportedValue,
-			"ResponseHeaderModifier Filter did not provide valid configuration to add/set/remove any headers",
-		)
+		updateRouteStatusForFilter(
+			filterContext,
+			"ResponseHeaderModifier Filter did not provide valid configuration to add/set/remove any headers")
 	}
 }
 
@@ -798,15 +695,9 @@ func (t *Translator) processExtensionRefHTTPFilter(extFilter *gwapiv1.LocalObjec
 					if filterContext.URLRewrite != nil {
 						if hasMultipleExtensionRewrites(hrf.Spec.URLRewrite, filterContext.URLRewrite) ||
 							hasConflictingExtensionAndCoreRewrites(hrf.Spec.URLRewrite, filterContext.URLRewrite) {
-							routeStatus := GetRouteStatus(filterContext.Route)
-							status.SetRouteStatusCondition(routeStatus,
-								filterContext.ParentRef.routeParentStatusIdx,
-								filterContext.Route.GetGeneration(),
-								gwapiv1.RouteConditionAccepted,
-								metav1.ConditionFalse,
-								gwapiv1.RouteReasonUnsupportedValue,
-								"Cannot configure multiple urlRewrite filters for a single HTTPRouteRule",
-							)
+							updateRouteStatusForFilter(
+								filterContext,
+								"Cannot configure multiple urlRewrite filters for a single HTTPRouteRule")
 							return
 						}
 					}
@@ -815,30 +706,16 @@ func (t *Translator) processExtensionRefHTTPFilter(extFilter *gwapiv1.LocalObjec
 						if hrf.Spec.URLRewrite.Path.Type == egv1a1.RegexHTTPPathModifier {
 							if hrf.Spec.URLRewrite.Path.ReplaceRegexMatch == nil ||
 								hrf.Spec.URLRewrite.Path.ReplaceRegexMatch.Pattern == "" {
-								errMsg := "ReplaceRegexMatch Pattern must be set when rewrite path type is \"ReplaceRegexMatch\""
-								routeStatus := GetRouteStatus(filterContext.Route)
-								status.SetRouteStatusCondition(routeStatus,
-									filterContext.ParentRef.routeParentStatusIdx,
-									filterContext.Route.GetGeneration(),
-									gwapiv1.RouteConditionAccepted,
-									metav1.ConditionFalse,
-									gwapiv1.RouteReasonUnsupportedValue,
-									errMsg,
-								)
+								updateRouteStatusForFilter(
+									filterContext,
+									"ReplaceRegexMatch Pattern must be set when rewrite path type is \"ReplaceRegexMatch\"")
 								return
 							} else if _, err := regexp.Compile(hrf.Spec.URLRewrite.Path.ReplaceRegexMatch.Pattern); err != nil {
 								// Avoid envoy NACKs due to invalid regex.
 								// Golang's regexp is almost identical to RE2: https://pkg.go.dev/regexp/syntax
-								errMsg := "ReplaceRegexMatch must be a valid RE2 regular expression"
-								routeStatus := GetRouteStatus(filterContext.Route)
-								status.SetRouteStatusCondition(routeStatus,
-									filterContext.ParentRef.routeParentStatusIdx,
-									filterContext.Route.GetGeneration(),
-									gwapiv1.RouteConditionAccepted,
-									metav1.ConditionFalse,
-									gwapiv1.RouteReasonUnsupportedValue,
-									errMsg,
-								)
+								updateRouteStatusForFilter(
+									filterContext,
+									"ReplaceRegexMatch must be a valid RE2 regular expression")
 								return
 							}
 
@@ -867,16 +744,9 @@ func (t *Translator) processExtensionRefHTTPFilter(extFilter *gwapiv1.LocalObjec
 						var hm *ir.HTTPHostModifier
 						if hrf.Spec.URLRewrite.Hostname.Type == egv1a1.HeaderHTTPHostnameModifier {
 							if hrf.Spec.URLRewrite.Hostname.Header == nil {
-								errMsg := "Header must be set when rewrite path type is \"Header\""
-								routeStatus := GetRouteStatus(filterContext.Route)
-								status.SetRouteStatusCondition(routeStatus,
-									filterContext.ParentRef.routeParentStatusIdx,
-									filterContext.Route.GetGeneration(),
-									gwapiv1.RouteConditionAccepted,
-									metav1.ConditionFalse,
-									gwapiv1.RouteReasonUnsupportedValue,
-									errMsg,
-								)
+								updateRouteStatusForFilter(
+									filterContext,
+									"Header must be set when rewrite path type is \"Header\"")
 								return
 							}
 							hm = &ir.HTTPHostModifier{
@@ -1031,14 +901,7 @@ func (t *Translator) processUnresolvedHTTPFilter(errMsg string, filterContext *H
 		gwapiv1.RouteReasonBackendNotFound,
 		errMsg,
 	)
-	status.SetRouteStatusCondition(routeStatus,
-		filterContext.ParentRef.routeParentStatusIdx,
-		filterContext.Route.GetGeneration(),
-		gwapiv1.RouteConditionAccepted,
-		metav1.ConditionFalse,
-		gwapiv1.RouteReasonUnsupportedValue,
-		errMsg,
-	)
+	updateRouteStatusForFilter(filterContext, errMsg)
 	filterContext.DirectResponse = &ir.CustomResponse{
 		StatusCode: ptr.To(uint32(500)),
 	}
@@ -1046,31 +909,16 @@ func (t *Translator) processUnresolvedHTTPFilter(errMsg string, filterContext *H
 
 func (t *Translator) processUnsupportedHTTPFilter(filterType string, filterContext *HTTPFiltersContext) {
 	errMsg := fmt.Sprintf("Unsupported filter type: %s", filterType)
-	routeStatus := GetRouteStatus(filterContext.Route)
-	status.SetRouteStatusCondition(routeStatus,
-		filterContext.ParentRef.routeParentStatusIdx,
-		filterContext.Route.GetGeneration(),
-		gwapiv1.RouteConditionAccepted,
-		metav1.ConditionFalse,
-		gwapiv1.RouteReasonUnsupportedValue,
-		errMsg,
-	)
+	updateRouteStatusForFilter(filterContext, errMsg)
 	filterContext.DirectResponse = &ir.CustomResponse{
 		StatusCode: ptr.To(uint32(500)),
 	}
 }
 
 func (t *Translator) processInvalidHTTPFilter(filterType string, filterContext *HTTPFiltersContext, err error) {
-	errMsg := fmt.Sprintf("Invalid filter %s: %v", filterType, err)
-	routeStatus := GetRouteStatus(filterContext.Route)
-	status.SetRouteStatusCondition(routeStatus,
-		filterContext.ParentRef.routeParentStatusIdx,
-		filterContext.Route.GetGeneration(),
-		gwapiv1.RouteConditionAccepted,
-		metav1.ConditionFalse,
-		gwapiv1.RouteReasonUnsupportedValue,
-		errMsg,
-	)
+	updateRouteStatusForFilter(
+		filterContext,
+		fmt.Sprintf("Invalid filter %s: %v", filterType, err))
 	filterContext.DirectResponse = &ir.CustomResponse{
 		StatusCode: ptr.To(uint32(500)),
 	}
diff --git a/internal/gatewayapi/route.go b/internal/gatewayapi/route.go
index 60ece038e..f39402b3d 100644
--- a/internal/gatewayapi/route.go
+++ b/internal/gatewayapi/route.go
@@ -16,6 +16,7 @@ import (
 	corev1 "k8s.io/api/core/v1"
 	discoveryv1 "k8s.io/api/discovery/v1"
 	metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
+	"k8s.io/apimachinery/pkg/util/sets"
 	"k8s.io/utils/ptr"
 	gwapiv1 "sigs.k8s.io/gateway-api/apis/v1"
 	gwapiv1a2 "sigs.k8s.io/gateway-api/apis/v1alpha2"
@@ -203,13 +204,13 @@ func (t *Translator) processHTTPRouteRules(httpRoute *HTTPRouteContext, parentRe
 			return nil, err
 		}
 
-		dstAddrTypeMap := make(map[ir.DestinationAddressType]int)
+		dstAddrTypeSet := make(sets.Set[ir.DestinationAddressType])
 		destName := irRouteDestinationName(httpRoute, ruleIdx)
 		for i, backendRef := range rule.BackendRefs {
 			settingName := irDestinationSettingName(destName, i)
 			ds, err := t.processDestination(settingName, backendRef, parentRef, httpRoute, resources)
 			if !t.IsEnvoyServiceRouting(envoyProxy) && ds != nil && len(ds.Endpoints) > 0 && ds.AddressType != nil {
-				dstAddrTypeMap[*ds.AddressType]++
+				dstAddrTypeSet.Insert(*ds.AddressType)
 			}
 
 			for _, route := range ruleRoutes {
@@ -240,7 +241,7 @@ func (t *Translator) processHTTPRouteRules(httpRoute *HTTPRouteContext, parentRe
 		}
 
 		// TODO: support mixed endpointslice address type between backendRefs
-		if !t.IsEnvoyServiceRouting(envoyProxy) && len(dstAddrTypeMap) > 1 {
+		if !t.IsEnvoyServiceRouting(envoyProxy) && (dstAddrTypeSet.Len() > 1 || dstAddrTypeSet.Has(ir.MIXED)) {
 			routeStatus := GetRouteStatus(httpRoute)
 			status.SetRouteStatusCondition(routeStatus,
 				parentRef.routeParentStatusIdx,
diff --git a/internal/gatewayapi/runner/runner.go b/internal/gatewayapi/runner/runner.go
index c90c3ba96..c8ae91240 100644
--- a/internal/gatewayapi/runner/runner.go
+++ b/internal/gatewayapi/runner/runner.go
@@ -73,6 +73,10 @@ func New(cfg *Config) *Runner {
 	}
 }
 
+// Close implements Runner interface.
+func (r *Runner) Close() error { return nil }
+
+// Name implements Runner interface.
 func (r *Runner) Name() string {
 	return string(egv1a1.LogComponentGatewayAPIRunner)
 }
diff --git a/internal/globalratelimit/runner/runner.go b/internal/globalratelimit/runner/runner.go
index e34303734..14818d172 100644
--- a/internal/globalratelimit/runner/runner.go
+++ b/internal/globalratelimit/runner/runner.go
@@ -62,6 +62,10 @@ type Runner struct {
 	Config
 }
 
+// Close implements Runner interface.
+func (r *Runner) Close() error { return nil }
+
+// Name implements Runner interface.
 func (r *Runner) Name() string {
 	return string(egv1a1.LogComponentGlobalRateLimitRunner)
 }
diff --git a/internal/infrastructure/host/infra.go b/internal/infrastructure/host/infra.go
index 71804561f..71deb9d3a 100644
--- a/internal/infrastructure/host/infra.go
+++ b/internal/infrastructure/host/infra.go
@@ -73,26 +73,9 @@ func NewInfra(runnerCtx context.Context, cfg *config.Server, logger logging.Logg
 		proxyContextMap: make(map[string]*proxyContext),
 		sdsConfigPath:   defaultLocalCertPathDir,
 	}
-	go infra.cleanProxy(runnerCtx)
-
 	return infra, nil
 }
 
-// cleanProxy stops all the running proxies when infra provider is closing.
-func (i *Infra) cleanProxy(ctx context.Context) {
-	<-ctx.Done()
-	if len(i.proxyContextMap) < 1 {
-		return
-	}
-
-	i.Logger.Info("start cleaning up proxies")
-	for name, proxyCtx := range i.proxyContextMap {
-		proxyCtx.cancel()
-		i.Logger.Info("proxy closed", "name", name)
-	}
-	i.Logger.Info("all proxies has been cleaned up")
-}
-
 // createSdsConfig creates the needing SDS config under certain directory.
 func createSdsConfig(dir string) error {
 	if err := file.Write(common.GetSdsCAConfigMapData(
diff --git a/internal/infrastructure/host/proxy_infra.go b/internal/infrastructure/host/proxy_infra.go
index 6c3625358..0da0002f6 100644
--- a/internal/infrastructure/host/proxy_infra.go
+++ b/internal/infrastructure/host/proxy_infra.go
@@ -8,6 +8,8 @@ package host
 import (
 	"context"
 	"errors"
+	"io"
+	"os"
 	"path/filepath"
 
 	funcE "github.com/tetratelabs/func-e/api"
@@ -20,9 +22,20 @@ import (
 	"github.com/envoyproxy/gateway/internal/xds/bootstrap"
 )
 
+// proxyContext corresponds to the context of the Envoy process.
 type proxyContext struct {
-	ctx    context.Context
+	// cancel is the function to cancel the context passed to the Envoy process.
 	cancel context.CancelFunc
+	// exit will receive an item when the Envoy process completely stopped, via funcE.ExitChannel.
+	exit chan struct{}
+}
+
+// Close implements the Manager interface.
+func (i *Infra) Close() error {
+	for name := range i.proxyContextMap {
+		i.stopEnvoy(name)
+	}
+	return nil
 }
 
 // CreateOrUpdateProxyInfra creates the managed host process, if it doesn't exist.
@@ -65,25 +78,46 @@ func (i *Infra) CreateOrUpdateProxyInfra(ctx context.Context, infra *ir.Infra) e
 	if err != nil {
 		return err
 	}
+	i.runEnvoy(ctx, os.Stdout, proxyName, args)
+	return nil
+}
 
-	// Create a new context for up-running proxy.
-	pCtx, cancel := context.WithCancel(context.Background())
-	i.proxyContextMap[proxyName] = &proxyContext{ctx: pCtx, cancel: cancel}
-	return funcE.Run(pCtx, args, funcE.HomeDir(i.HomeDir))
+// runEnvoy runs the Envoy process with the given arguments and name in a separate goroutine.
+func (i *Infra) runEnvoy(ctx context.Context, out io.Writer, name string, args []string) {
+	pCtx, cancel := context.WithCancel(ctx)
+	exit := make(chan struct{}, 1)
+	i.proxyContextMap[name] = &proxyContext{cancel: cancel, exit: exit}
+	go func() {
+		// Run blocks until pCtx is done or the process exits where the latter doesn't happen when
+		// Envoy successfully starts up. So, this will not return until pCtx is done in practice.
+		defer func() {
+			exit <- struct{}{}
+		}()
+		err := funcE.Run(pCtx, args, funcE.HomeDir(i.HomeDir), funcE.Out(out))
+		if err != nil {
+			i.Logger.Error(err, "failed to run envoy")
+		}
+	}()
 }
 
 // DeleteProxyInfra removes the managed host process, if it doesn't exist.
-func (i *Infra) DeleteProxyInfra(ctx context.Context, infra *ir.Infra) error {
+func (i *Infra) DeleteProxyInfra(_ context.Context, infra *ir.Infra) error {
 	if infra == nil {
 		return errors.New("infra ir is nil")
 	}
 
 	proxyInfra := infra.GetProxyInfra()
 	proxyName := utils.GetHashedName(proxyInfra.Name, 64)
+	i.stopEnvoy(proxyName)
+	return nil
+}
+
+// stopEnvoy stops the Envoy process by its name. It will block until the process completely stopped.
+func (i *Infra) stopEnvoy(proxyName string) {
 	if pCtx, ok := i.proxyContextMap[proxyName]; ok {
-		pCtx.cancel()
+		pCtx.cancel()    // Cancel causes the Envoy process to exit.
+		<-pCtx.exit      // Wait for the Envoy process to completely exit.
+		close(pCtx.exit) // Close the channel to avoid leaking.
+		delete(i.proxyContextMap, proxyName)
 	}
-
-	// Return directly if the proxy is already stopped.
-	return nil
 }
diff --git a/internal/infrastructure/kubernetes/infra.go b/internal/infrastructure/kubernetes/infra.go
index 4285f3959..a0615a4e8 100644
--- a/internal/infrastructure/kubernetes/infra.go
+++ b/internal/infrastructure/kubernetes/infra.go
@@ -70,6 +70,9 @@ func NewInfra(cli client.Client, cfg *config.Server) *Infra {
 	}
 }
 
+// Close implements Manager interface.
+func (i *Infra) Close() error { return nil }
+
 // createOrUpdate creates a ServiceAccount/ConfigMap/Deployment/Service in the kube api server based on the
 // provided ResourceRender, if it doesn't exist and updates it if it does.
 func (i *Infra) createOrUpdate(ctx context.Context, r ResourceRender) error {
diff --git a/internal/infrastructure/kubernetes/proxy/resource.go b/internal/infrastructure/kubernetes/proxy/resource.go
index 13d462cb6..7c096266d 100644
--- a/internal/infrastructure/kubernetes/proxy/resource.go
+++ b/internal/infrastructure/kubernetes/proxy/resource.go
@@ -163,6 +163,19 @@ func expectedProxyContainers(infra *ir.ProxyInfra,
 				SuccessThreshold: 1,
 				FailureThreshold: 1,
 			},
+			LivenessProbe: &corev1.Probe{
+				ProbeHandler: corev1.ProbeHandler{
+					HTTPGet: &corev1.HTTPGetAction{
+						Path:   bootstrap.EnvoyReadinessPath,
+						Port:   intstr.IntOrString{Type: intstr.Int, IntVal: bootstrap.EnvoyReadinessPort},
+						Scheme: corev1.URISchemeHTTP,
+					},
+				},
+				TimeoutSeconds:   1,
+				PeriodSeconds:    10,
+				SuccessThreshold: 1,
+				FailureThreshold: 3,
+			},
 			Lifecycle: &corev1.Lifecycle{
 				PreStop: &corev1.LifecycleHandler{
 					HTTPGet: &corev1.HTTPGetAction{
diff --git a/internal/infrastructure/kubernetes/ratelimit/resource.go b/internal/infrastructure/kubernetes/ratelimit/resource.go
index 4785a700d..ddcd793c4 100644
--- a/internal/infrastructure/kubernetes/ratelimit/resource.go
+++ b/internal/infrastructure/kubernetes/ratelimit/resource.go
@@ -190,6 +190,19 @@ func expectedRateLimitContainers(rateLimit *egv1a1.RateLimit, rateLimitDeploymen
 				SuccessThreshold: 1,
 				FailureThreshold: 1,
 			},
+			LivenessProbe: &corev1.Probe{
+				ProbeHandler: corev1.ProbeHandler{
+					HTTPGet: &corev1.HTTPGetAction{
+						Path:   ReadinessPath,
+						Port:   intstr.IntOrString{Type: intstr.Int, IntVal: ReadinessPort},
+						Scheme: corev1.URISchemeHTTP,
+					},
+				},
+				TimeoutSeconds:   1,
+				PeriodSeconds:    10,
+				SuccessThreshold: 1,
+				FailureThreshold: 3,
+			},
 		},
 	}
 
diff --git a/internal/infrastructure/manager.go b/internal/infrastructure/manager.go
index 0254eb185..3e1a0d811 100644
--- a/internal/infrastructure/manager.go
+++ b/internal/infrastructure/manager.go
@@ -28,6 +28,8 @@ var (
 
 // Manager provides the scaffolding for managing infrastructure.
 type Manager interface {
+	// Close is called when Envoy Gateway is shutting down, it can be used to block until all resources are cleaned up.
+	Close() error
 	// CreateOrUpdateProxyInfra creates or updates infra.
 	CreateOrUpdateProxyInfra(ctx context.Context, infra *ir.Infra) error
 	// DeleteProxyInfra deletes infra.
diff --git a/internal/infrastructure/runner/runner.go b/internal/infrastructure/runner/runner.go
index 72beff9c2..4de124caf 100644
--- a/internal/infrastructure/runner/runner.go
+++ b/internal/infrastructure/runner/runner.go
@@ -28,6 +28,12 @@ type Runner struct {
 	mgr infrastructure.Manager
 }
 
+// Close implements Runner interface.
+func (r *Runner) Close() error {
+	return r.mgr.Close()
+}
+
+// Name implements Runner interface.
 func (r *Runner) Name() string {
 	return string(egv1a1.LogComponentInfrastructureRunner)
 }
diff --git a/internal/ir/xds.go b/internal/ir/xds.go
index 9986a0240..40801926a 100644
--- a/internal/ir/xds.go
+++ b/internal/ir/xds.go
@@ -43,6 +43,7 @@ var (
 	ErrTLSPrivateKey                            = errors.New("field PrivateKey must be specified")
 	ErrRouteNameEmpty                           = errors.New("field Name must be specified")
 	ErrHTTPRouteHostnameEmpty                   = errors.New("field Hostname must be specified")
+	ErrRouteDestinationsFQDNMixed               = errors.New("mixed endpoints address type for the same route destination is not supported")
 	ErrDestinationNameEmpty                     = errors.New("field Name must be specified")
 	ErrDestEndpointHostInvalid                  = errors.New("field Address must be a valid IP or FQDN address")
 	ErrDestEndpointPortInvalid                  = errors.New("field Port specified is invalid")
@@ -1429,10 +1430,17 @@ func (r *RouteDestination) Validate() error {
 	if len(r.Name) == 0 {
 		errs = errors.Join(errs, ErrDestinationNameEmpty)
 	}
+	routeHasAddressTypes := make(sets.Set[DestinationAddressType])
 	for _, s := range r.Settings {
 		if err := s.Validate(); err != nil {
 			errs = errors.Join(errs, err)
 		}
+		if s.AddressType != nil {
+			routeHasAddressTypes.Insert(*s.AddressType)
+		}
+	}
+	if routeHasAddressTypes.Len() > 1 || routeHasAddressTypes.Has(MIXED) {
+		errs = errors.Join(ErrRouteDestinationsFQDNMixed)
 	}
 
 	return errs
diff --git a/internal/kubernetes/client.go b/internal/kubernetes/client.go
index 5c58242ba..621df56d2 100644
--- a/internal/kubernetes/client.go
+++ b/internal/kubernetes/client.go
@@ -16,6 +16,7 @@ import (
 	"k8s.io/apimachinery/pkg/runtime"
 	"k8s.io/apimachinery/pkg/runtime/serializer"
 	"k8s.io/apimachinery/pkg/types"
+	"k8s.io/apimachinery/pkg/util/httpstream"
 	"k8s.io/client-go/kubernetes"
 	kubescheme "k8s.io/client-go/kubernetes/scheme"
 	"k8s.io/client-go/rest"
@@ -163,6 +164,20 @@ func (c *client) PodExec(namespacedName types.NamespacedName, container string,
 		return "", "", err
 	}
 
+	// WebSocketExecutor must be "GET" method as described in RFC 6455 Sec. 4.1 (page 17).
+	websocketExec, err := remotecommand.NewWebSocketExecutor(c.config, "GET", req.URL().String())
+	if err != nil {
+		return "", "", err
+	}
+
+	// Prefer to Websocket, fallback to SPDY
+	exec, err = remotecommand.NewFallbackExecutor(websocketExec, exec, func(err error) bool {
+		return httpstream.IsUpgradeFailure(err) || httpstream.IsHTTPSProxyError(err)
+	})
+	if err != nil {
+		return "", "", err
+	}
+
 	var stdoutBuf, stderrBuf bytes.Buffer
 	err = exec.StreamWithContext(context.Background(), remotecommand.StreamOptions{
 		Stdin:  nil,
diff --git a/internal/kubernetes/port_forwarder.go b/internal/kubernetes/port_forwarder.go
index 8e88b9c02..e112056cf 100644
--- a/internal/kubernetes/port_forwarder.go
+++ b/internal/kubernetes/port_forwarder.go
@@ -14,6 +14,7 @@ import (
 	"strconv"
 
 	"k8s.io/apimachinery/pkg/types"
+	"k8s.io/apimachinery/pkg/util/httpstream"
 	"k8s.io/client-go/rest"
 	"k8s.io/client-go/tools/portforward"
 	"k8s.io/client-go/transport/spdy"
@@ -113,6 +114,15 @@ func (f *localForwarder) buildKubernetesPortForwarder(readyCh chan struct{}) (*p
 	}
 
 	dialer := spdy.NewDialer(upgrader, &http.Client{Transport: roundTripper}, http.MethodPost, serverURL)
+	tunnelingDialer, err := portforward.NewSPDYOverWebsocketDialer(serverURL, f.RESTConfig())
+	if err != nil {
+		return nil, err
+	}
+	// Prefer Websocket dialer, fallback to SPDY dialer.
+	dialer = portforward.NewFallbackDialer(tunnelingDialer, dialer, func(err error) bool {
+		return httpstream.IsUpgradeFailure(err) || httpstream.IsHTTPSProxyError(err)
+	})
+
 	fw, err := portforward.NewOnAddresses(dialer,
 		[]string{netutil.DefaultLocalAddress},
 		[]string{fmt.Sprintf("%d:%d", f.localPort, f.podPort)},
diff --git a/internal/provider/kubernetes/controller.go b/internal/provider/kubernetes/controller.go
index 9ed0445fe..07370f27e 100644
--- a/internal/provider/kubernetes/controller.go
+++ b/internal/provider/kubernetes/controller.go
@@ -215,8 +215,7 @@ func (r *gatewayAPIReconciler) Reconcile(ctx context.Context, _ reconcile.Reques
 					string(gwapiv1.GatewayClassReasonInvalidParameters),
 					msg)
 				r.resources.GatewayClassStatuses.Store(utils.NamespacedName(gc), &gc.Status)
-				r.log.Error(err, "failed to process parametersRef for gatewayclass", "name", managedGC.Name)
-				return reconcile.Result{}, err
+				return reconcile.Result{}, nil
 			}
 		}
 
diff --git a/internal/provider/runner/runner.go b/internal/provider/runner/runner.go
index d4be9020c..673ea867d 100644
--- a/internal/provider/runner/runner.go
+++ b/internal/provider/runner/runner.go
@@ -32,11 +32,15 @@ func New(cfg *Config) *Runner {
 	return &Runner{Config: *cfg}
 }
 
+// Close implements Runner interface.
+func (r *Runner) Close() error { return nil }
+
+// Name implements Runner interface.
 func (r *Runner) Name() string {
 	return string(egv1a1.LogComponentProviderRunner)
 }
 
-// Start the provider runner
+// Start implements Runner interface.
 func (r *Runner) Start(ctx context.Context) (err error) {
 	r.Logger = r.Logger.WithName(r.Name()).WithValues("runner", r.Name())
 
@@ -61,7 +65,7 @@ func (r *Runner) Start(ctx context.Context) (err error) {
 
 	r.Logger.Info("Running provider", "type", p.Type())
 	go func() {
-		if err = p.Start(ctx); err != nil {
+		if err := p.Start(ctx); err != nil {
 			r.Logger.Error(err, "unable to start provider")
 		}
 	}()
diff --git a/internal/xds/server/runner/runner.go b/internal/xds/server/runner/runner.go
index d73cb7ccd..71d2e7ba5 100644
--- a/internal/xds/server/runner/runner.go
+++ b/internal/xds/server/runner/runner.go
@@ -76,6 +76,9 @@ func (r *Runner) Name() string {
 	return string(egv1a1.LogComponentXdsServerRunner)
 }
 
+// Close implements Runner interface.
+func (r *Runner) Close() error { return nil }
+
 // Start starts the xds-server runner
 func (r *Runner) Start(ctx context.Context) (err error) {
 	r.Logger = r.Logger.WithName(r.Name()).WithValues("runner", r.Name())
diff --git a/internal/xds/translator/runner/runner.go b/internal/xds/translator/runner/runner.go
index faa4a65ec..3be972c52 100644
--- a/internal/xds/translator/runner/runner.go
+++ b/internal/xds/translator/runner/runner.go
@@ -37,6 +37,10 @@ func New(cfg *Config) *Runner {
 	return &Runner{Config: *cfg}
 }
 
+// Close implements Runner interface.
+func (r *Runner) Close() error { return nil }
+
+// Name implements Runner interface.
 func (r *Runner) Name() string {
 	return string(egv1a1.LogComponentXdsTranslatorRunner)
 }
diff --git a/release-notes/current.yaml b/release-notes/current.yaml
index c995a3e06..cfcf361c8 100644
--- a/release-notes/current.yaml
+++ b/release-notes/current.yaml
@@ -24,6 +24,7 @@ new features: |
   Added support for zone aware routing
   Added support for BackendTLSPolicy to target ServiceImport
   Added support for per-host circuit breaker thresholds
+  Added support for egctl Websocket in addation to SPDY
 
 bug fixes: |
   Fix traffic splitting when filters are attached to the backendRef.
@@ -33,6 +34,7 @@ bug fixes: |
   Fix an issue that stats compressor was not working.
   Added support for BackendTLSPolicy and EnvoyExtensionPolicy parsing in Standalone mode.
   Retrigger reconciliation when backendRef of type ServiceImport is updated or when EndpointSlice(s) for a ServiceImport are updated.
+  Fix not logging an error and returning it in the K8s Reconcile method when a GatewayClass is not accepted.
 
 # Enhancements that improve performance.
 performance improvements: |
diff --git a/site/content/en/contributions/RELEASING.md b/site/content/en/contributions/RELEASING.md
index 7f18ab47b..bdd6b4668 100644
--- a/site/content/en/contributions/RELEASING.md
+++ b/site/content/en/contributions/RELEASING.md
@@ -9,7 +9,10 @@ This document guides maintainers through the process of creating an Envoy Gatewa
   - [Prerequisites](#prerequisites)
 - [Minor Release](#minor-release)
   - [Prerequisites](#prerequisites-1)
-- [Announce the Release](#announce-the-release)
+  - [Announce the Release](#announce-the-release)
+- [Patch Release](#patch-release)
+  - [Prerequisites](#prerequisites-2)
+  - [Announce the Release](#announce-the-release-1)
 
 ## Release Candidate
 
@@ -109,7 +112,7 @@ export GITHUB_REMOTE=origin
    1. Generate the versioned release docs:
 
       ``` shell
-         make docs-release TAG=v${MAJOR_VERSION}.${MINOR_VERSION}.0
+      make docs-release TAG=v${MAJOR_VERSION}.${MINOR_VERSION}.0
       ```
 
    1. Update `site/layouts/shortcodes/helm-version.html`, add the latest version of the minor release, and update the short code for `{{- with (strings.HasPrefix $pagePrefix "doc") -}}` to the latest minor version.
@@ -148,12 +151,13 @@ export GITHUB_REMOTE=origin
       {{- end -}}
       ```
       
-   1. Update `site/layouts/partials/page-meta-links.html`, change the version to current major version.
+   1. Update `site/hugo.toml`, change the version to current major version.
 
       ```console
-      {{ with (strings.HasPrefix $path "docs") -}}
-      {{ $path = replaceRE "docs" "v1.3" $path -}}
-      {{ end -}}
+      # The version number for the version of the docs represented in this doc set.
+      # Used in the "version-banner" partial to display a version number for the
+      # current doc set.
+      version = "v1.3"
       ```  
 
 3. Sign, commit, and push your changes to your fork.
diff --git a/site/content/en/v1.3/install/install-helm.md b/site/content/en/v1.3/install/install-helm.md
index 16975efc8..d146194d3 100644
--- a/site/content/en/v1.3/install/install-helm.md
+++ b/site/content/en/v1.3/install/install-helm.md
@@ -63,7 +63,7 @@ consideration when debugging.
 
 [Helm](https://helm.sh/docs/chart_best_practices/custom_resource_definitions/#some-caveats-and-explanations) does not update CRDs
 that live in the `/crds` folder in the Helm Chart. So you will manually need to update the CRDs.
-Follow the steps outlined in [this](./install-yaml/#upgrading-from-v1.1) section if you're upgrading from a previous version.
+Follow the steps outlined in [this](./install-yaml/#upgrading-from-v1.2) section if you're upgrading from a previous version.
 
 ## Helm chart customizations
 
@@ -130,20 +130,22 @@ These are the ports used by Envoy Gateway and the managed Envoy Proxy.
 
 ### Envoy Gateway
 
-| Envoy Gateway          | Address   |  Port  |  Configurable  |
-|:----------------------:|:---------:|:------:|    :------:    |
-| Xds EnvoyProxy Server  | 0.0.0.0   | 18000  |       No       |
-| Xds RateLimit Server   | 0.0.0.0   | 18001  |       No       |
-| Admin Server           | 127.0.0.1 | 19000  |       Yes      |
-| Metrics Server         |  0.0.0.0  | 19001  |       No       |
-| Health Check           | 127.0.0.1 |  8081  |       No       |
+|     Envoy Gateway     |  Address  | Port  | Configurable |
+| :-------------------: | :-------: | :---: | :----------: |
+| Xds EnvoyProxy Server |  0.0.0.0  | 18000 |      No      |
+| Xds RateLimit Server  |  0.0.0.0  | 18001 |      No      |
+|     Admin Server      | 127.0.0.1 | 19000 |     Yes      |
+|    Metrics Server     |  0.0.0.0  | 19001 |      No      |
+|     Health Check      | 127.0.0.1 | 8081  |      No      |
 
 ### EnvoyProxy
 
-| Envoy Proxy                       | Address     | Port    |
-|:---------------------------------:|:-----------:| :-----: |
-| Admin Server                      | 127.0.0.1   | 19000   |
-| Heath Check  | 0.0.0.0     | 19001   |
+|   Envoy Proxy    |  Address  | Port  |
+| :--------------: | :-------: | :---: |
+|   Admin Server   | 127.0.0.1 | 19000 |
+|      Stats       |  0.0.0.0  | 19001 |
+| Shutdown Manager |  0.0.0.0  | 19002 |
+|    Readiness     |  0.0.0.0  | 19003 |
 
 {{% alert title="Next Steps" color="warning" %}}
 Envoy Gateway should now be successfully installed and running.  To experience more abilities of Envoy Gateway, refer to [Tasks](../tasks).
diff --git a/site/content/en/v1.3/install/install-yaml.md b/site/content/en/v1.3/install/install-yaml.md
index 0da5ca9cc..eac18063e 100644
--- a/site/content/en/v1.3/install/install-yaml.md
+++ b/site/content/en/v1.3/install/install-yaml.md
@@ -38,14 +38,11 @@ Refer to the [Developer Guide](../../contributions/develop) to learn more.
 
    Envoy Gateway should now be successfully installed and running, but in order to experience more abilities of Envoy Gateway, you can refer to [Tasks](/latest/tasks).
 
-## Upgrading from v1.1
+## Upgrading from v1.2
 
-Some manual migration steps are required to upgrade Envoy Gateway to v1.2.
+Some manual migration steps are required to upgrade Envoy Gateway to v1.3.
 
-1. Update your `GRPCRoute` and `ReferenceGrant` resources if the storage version being used is `v1alpha2`.
-Follow the steps in Gateway-API [v1.2 Upgrade Notes](https://gateway-api.sigs.k8s.io/guides/#v12-upgrade-notes)
-
-2. Update Gateway-API and Envoy Gateway CRDs:
+1. Update Gateway-API and Envoy Gateway CRDs:
 
 ```shell
 helm pull oci://docker.io/envoyproxy/gateway-helm --version {{< yaml-version >}} --untar
@@ -53,7 +50,7 @@ kubectl apply --force-conflicts --server-side -f ./gateway-helm/crds/gatewayapi-
 kubectl apply --force-conflicts --server-side -f ./gateway-helm/crds/generated
 ```
 
-3. Install Envoy Gateway {{< yaml-version >}}:
+2. Install Envoy Gateway {{< yaml-version >}}:
 
 ```shell
 helm upgrade eg oci://docker.io/envoyproxy/gateway-helm --version {{< yaml-version >}} -n envoy-gateway-system
diff --git a/site/data/adopters.yaml b/site/data/adopters.yaml
index e47a7cdb8..d1a3c56e8 100644
--- a/site/data/adopters.yaml
+++ b/site/data/adopters.yaml
@@ -51,3 +51,8 @@ adopters:
     logo: "/logos/docker.png"
     url: "https://www.docker.com/"
     description: "Docker is using Envoy Gateway to route all internal traffic for Docker Hub."
+  - name: "SenseTime"
+    logo: "/logos/sensetime.png"
+    url: "https://www.sensetime.com/"
+    description: "SenseTime is using Envoy Gateway to route most traffic for SenseCore."
+
diff --git a/site/data/ecosystem.yaml b/site/data/ecosystem.yaml
index 58b1f3d93..b71607988 100644
--- a/site/data/ecosystem.yaml
+++ b/site/data/ecosystem.yaml
@@ -3,3 +3,15 @@ adopters:
     logo: "/logos/envoy-ai-gateway.svg"
     url: "https://aigateway.envoyproxy.io"
     description: "Envoy AI Gateway is built on top of Envoy Gateway to handle request traffic from application services to Gen AI services."
+  - name: "Kuadrant"
+    logo: "/logos/kuadrant.svg"
+    url: "https://kuadrant.io"
+    description: "Kuadrant extends gateways and routes managed by Envoy Gateway with additional policy capabilities to enhance application connectivity and security."
+  - name: "AIBrix"
+    logo: "/logos/aibrix.png"
+    url: "https://aibrix.readthedocs.io"
+    description: "AIBrix provides building blocks for scalable GenAI inference infrastructure and leverages Envoy Gateway to deploy advanced routing strategies for LLM requests sent to Inference engines"
+  - name: "Knative"
+    logo: "/logos/knative.png"
+    url: "https://knative.dev"
+    description: "Knative's net-gateway-api integrates with Envoy Gateway by implementing the Kubernetes Gateway API, enabling Knative services to utilize Envoy Gateway for ingress traffic management."
diff --git a/site/hugo.toml b/site/hugo.toml
index 5279041bf..51e8b886a 100644
--- a/site/hugo.toml
+++ b/site/hugo.toml
@@ -107,11 +107,11 @@ archived_version = false
 # The version number for the version of the docs represented in this doc set.
 # Used in the "version-banner" partial to display a version number for the
 # current doc set.
-version = "latest"
+version = "v1.3"
 
 # A link to latest version of the docs. Used in the "version-banner" partial to
 # point people to the main doc site.
-url_latest_version = "https://gateway.envoyproxy.io"
+url_latest_version = "/docs"
 
 # Repository configuration (URLs for in-page links to opening issues and suggesting changes)
 github_repo = "https://github.com/envoyproxy/gateway"
@@ -227,39 +227,49 @@ enable = true
 [[params.versions]]
   version = "latest"
   url = "/latest"
+  eol = "2099-12-31"
 
 [[params.versions]]
   version = "v1.3"
   url = "/v1.3"
+  eol = "2025-07-30"
 
 [[params.versions]]
   version = "v1.2"
-  url = "/docs"
+  url = "/v1.2"
+  eol = "2025-05-06"
 
 [[params.versions]]
   version = "v1.1"
   url = "/v1.1"
+  eol = "2025-01-22"
 
 [[params.versions]]
   version = "v1.0"
   url = "/v1.0"
+  eol = "2024-09-13"
 
 [[params.versions]]
   version = "v0.6"
   url = "/v0.6"
+  eol = "2024-05-02"
 
 [[params.versions]]
   version = "v0.5"
   url = "/v0.5"
+  eol = "2024-01-02"
 
 [[params.versions]]
   version = "v0.4"
   url = "/v0.4"
+  eol = "2023-10-24"
 
 [[params.versions]]
   version = "v0.3"
   url = "/v0.3"
+  eol = "2023-08-09"
 
 [[params.versions]]
   version = "v0.2"
   url = "/v0.2"
+  eol = "2023-04-20"
diff --git a/site/layouts/partials/navbar-version-selector.html b/site/layouts/partials/navbar-version-selector.html
index fa547de96..6a20affcd 100644
--- a/site/layouts/partials/navbar-version-selector.html
+++ b/site/layouts/partials/navbar-version-selector.html
@@ -1,4 +1,5 @@
 {{ $baseURL := .Site.BaseURL }}
+{{ $current_version := .Site.Params.version }}
 <div class="dropdown">
     <a class="nav-link dropdown-toggle" href="#" role="button" data-bs-toggle="dropdown" aria-haspopup="true" aria-expanded="false">
         {{- .Site.Params.version_menu -}}
@@ -9,11 +10,20 @@
         {{ $path = .Page.RelPermalink -}}
         {{ end -}}
         {{ range .Site.Params.versions -}}
+        {{ $url := .url }}
+        {{ if eq .version $current_version }}
+        {{ $url = "/docs" }}
+        {{ end -}}
+        {{ $text := .version }}
+        {{ $eol_time := time.AsTime .eol }}
+        {{ if gt (time.Now.Sub $eol_time) 0 }}
+        {{ $text = printf "%s (EOL)" .version }}
+        {{ end -}}
+        {{ $href := printf "%s%s" $url $path -}}
         {{ if ne $baseURL "/" }}
-        <li><a class="dropdown-item" href="{{ $baseURL }}{{ .url }}{{ $path }}">{{ .version }}</a></li>
-        {{ else }}
-        <li><a class="dropdown-item" href="{{ .url }}{{ $path }}">{{ .version }}</a></li>
+        {{ $href := printf "%s%s%s" $baseURL $url $path -}}
         {{ end }}
+        <li><a class="dropdown-item" href="{{ $href }}">{{ $text }}</a></li>
         {{ end -}}
     </ul>
 </div>
\ No newline at end of file
diff --git a/site/layouts/partials/page-meta-links.html b/site/layouts/partials/page-meta-links.html
index 3c3450c8d..b09dff7ec 100644
--- a/site/layouts/partials/page-meta-links.html
+++ b/site/layouts/partials/page-meta-links.html
@@ -1,6 +1,8 @@
 {{/* cSpell:ignore querify subdir */ -}}
 {{/* Class names ending with `--KIND` are deprecated in favor of `__KIND`, but we're keeping them for a few releases after 0.9.0 */ -}}
 
+{{ $current_version := .Site.Params.version }}
+
 {{ if .File -}}
 {{ $path := strings.TrimPrefix (add hugo.WorkingDir "/") $.File.Filename -}}
 {{ $gh_repo := $.Param "github_repo" -}}
@@ -26,7 +28,7 @@
   {{ end -}}
   {{/* Adjust the alias path for current version */ -}}
   {{ with (strings.Contains $path "docs") -}}
-    {{ $path = replaceRE "docs" "v1.3" $path -}}
+    {{ $path = replaceRE "docs" $current_version $path -}}
   {{ end -}}
 
   {{ $gh_repo_path := printf "%s/%s/%s" $gh_branch $gh_subdir $path -}}
diff --git a/site/layouts/partials/version-banner.html b/site/layouts/partials/version-banner.html
new file mode 100644
index 000000000..91b70fd2a
--- /dev/null
+++ b/site/layouts/partials/version-banner.html
@@ -0,0 +1,19 @@
+{{ $color := "primary" }}
+{{ $latest_version := .Site.Params.url_latest_version }}
+{{ $path := strings.TrimPrefix (add hugo.WorkingDir "/content/en/") $.File.Filename -}}
+{{ range .Site.Params.versions -}}
+
+{{ $eol_time := time.AsTime .eol }}
+{{ if gt (time.Now.Sub $eol_time) 0 }}
+
+{{ if strings.HasPrefix $path .version }}
+<div class="alert alert-warning">
+    Notice: You're viewing documentation for an older version of Envoy Gateway that has reached End of Life (EOL).
+    <br />
+    Please refer to the <a href="{{ $latest_version | safeURL }}" target="_blank">/docs</a> documentation for the most current information.
+</div>
+{{ end }}
+
+{{ end }}
+
+{{ end }}
diff --git a/site/static/logos/aibrix.png b/site/static/logos/aibrix.png
new file mode 100644
index 000000000..eb8e43820
Binary files /dev/null and b/site/static/logos/aibrix.png differ
diff --git a/site/static/logos/knative.png b/site/static/logos/knative.png
new file mode 100644
index 000000000..56816839e
Binary files /dev/null and b/site/static/logos/knative.png differ
diff --git a/site/static/logos/kuadrant.svg b/site/static/logos/kuadrant.svg
new file mode 100644
index 000000000..022ffd214
--- /dev/null
+++ b/site/static/logos/kuadrant.svg
@@ -0,0 +1,12 @@
+<svg width="400" height="200" viewBox="0 0 1024 150" version="1.1" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" xml:space="preserve" xmlns:serif="http://www.serif.com/" style="fill-rule:evenodd;clip-rule:evenodd;stroke-linejoin:round;stroke-miterlimit:2;">
+    <path d="M278.63,76.64L316,28.52L353.84,28.52L307.08,83.76L358.21,145.2L318.5,145.2L278.63,94.59L278.63,145.2L248,145.2L248,28.52L278.65,28.52L278.63,76.64Z" style="fill-rule:nonzero;"></path>
+    <path d="M392.61,65.81L392.61,110.53C392.61,120.33 397.403,125.23 406.99,125.23C416.577,125.23 421.37,120.33 421.37,110.53L421.37,65.81L449.67,65.81L449.67,116C449.67,126.733 446.1,134.78 438.96,140.14C431.82,145.5 421.153,148.167 406.96,148.14C392.78,148.14 382.113,145.473 374.96,140.14C367.807,134.807 364.257,126.76 364.31,116L364.31,65.81L392.61,65.81Z" style="fill-rule:nonzero;"></path>
+    <path d="M530.82,65.81L559.27,65.81L559.27,145.2L530.82,145.2L530.82,136.37C524.767,143.91 516.583,147.677 506.27,147.67C500.743,147.73 495.262,146.651 490.17,144.5C485.336,142.436 480.973,139.408 477.35,135.6C473.654,131.714 470.756,127.141 468.82,122.14C466.765,116.756 465.747,111.032 465.82,105.27C465.802,99.74 466.82,94.256 468.82,89.1C470.672,84.158 473.448,79.614 477,75.71C484.47,67.662 495.021,63.158 506,63.33C516,63.33 524.287,66.787 530.86,73.7L530.82,65.81ZM495.17,105.27C495.135,110.123 497.02,114.798 500.41,118.27C502.052,119.941 504.02,121.258 506.19,122.14C508.497,123.081 510.969,123.553 513.46,123.53C515.902,123.544 518.322,123.071 520.58,122.14C522.75,121.258 524.718,119.941 526.36,118.27C527.989,116.604 529.313,114.664 530.27,112.54C531.272,110.344 531.781,107.954 531.76,105.54C531.764,103.128 531.256,100.742 530.27,98.54C529.326,96.387 528.001,94.423 526.36,92.74C524.718,91.069 522.75,89.752 520.58,88.87C518.323,87.936 515.903,87.46 513.46,87.47C510.968,87.45 508.497,87.926 506.19,88.87C504.02,89.752 502.052,91.069 500.41,92.74C498.804,94.374 497.506,96.284 496.58,98.38C495.629,100.551 495.148,102.9 495.17,105.27Z" style="fill-rule:nonzero;"></path>
+    <path d="M640.42,16.75L668.88,16.75L668.88,145.2L640.42,145.2L640.42,136.37C634.373,143.91 626.19,147.677 615.87,147.67C610.334,147.733 604.848,146.625 599.77,144.42C594.942,142.301 590.584,139.241 586.95,135.42C583.262,131.545 580.367,126.986 578.43,122C574.421,111.42 574.364,99.739 578.27,89.12C580.104,84.163 582.894,79.613 586.48,75.73C590.076,71.901 594.41,68.84 599.22,66.73C604.367,64.47 609.939,63.334 615.56,63.4C625.56,63.4 633.847,66.857 640.42,73.77L640.42,16.75ZM604.77,105.27C604.735,110.123 606.62,114.798 610.01,118.27C611.652,119.941 613.62,121.258 615.79,122.14C618.1,123.082 620.575,123.554 623.07,123.53C625.509,123.544 627.926,123.071 630.18,122.14C632.35,121.258 634.318,119.941 635.96,118.27C637.589,116.604 638.913,114.664 639.87,112.54C640.872,110.344 641.381,107.954 641.36,105.54C641.364,103.128 640.856,100.742 639.87,98.54C638.926,96.387 637.601,94.423 635.96,92.74C634.318,91.069 632.35,89.752 630.18,88.87C625.622,87.004 620.508,87.004 615.95,88.87C613.78,89.752 611.812,91.069 610.17,92.74C608.556,94.384 607.233,96.292 606.26,98.38C605.259,100.538 604.75,102.891 604.77,105.27Z" style="fill-rule:nonzero;"></path>
+    <path d="M688.1,65.81L716.4,65.81L716.4,78.81C719.155,74.323 722.966,70.577 727.5,67.9C732.181,65.295 737.474,63.986 742.83,64.11L745.25,64.11C746.257,64.125 747.261,64.229 748.25,64.42L748.25,91.19C744.457,89.321 740.278,88.365 736.05,88.4C729.49,88.4 724.567,90.333 721.28,94.2C717.993,98.067 716.35,103.733 716.35,111.2L716.35,145.2L688.1,145.2L688.1,65.81Z" style="fill-rule:nonzero;"></path>
+    <path d="M823.82,65.81L852.27,65.81L852.27,145.2L823.82,145.2L823.82,136.37C817.767,143.91 809.583,147.677 799.27,147.67C793.74,147.73 788.256,146.651 783.16,144.5C778.327,142.434 773.965,139.406 770.34,135.6C766.644,131.716 763.749,127.142 761.82,122.14C759.748,116.76 758.713,111.035 758.77,105.27C758.752,99.74 759.77,94.256 761.77,89.1C763.634,84.152 766.427,79.607 770,75.71C777.467,67.658 788.02,63.153 799,63.33C809,63.33 817.287,66.787 823.86,73.7L823.82,65.81ZM788.17,105.27C788.126,110.123 790.008,114.8 793.4,118.27C795.048,119.939 797.018,121.255 799.19,122.14C801.497,123.082 803.968,123.554 806.46,123.53C808.899,123.544 811.316,123.071 813.57,122.14C815.742,121.255 817.712,119.939 819.36,118.27C820.986,116.601 822.309,114.662 823.27,112.54C824.269,110.343 824.775,107.953 824.75,105.54C824.757,103.128 824.252,100.743 823.27,98.54C822.322,96.389 820.998,94.425 819.36,92.74C817.712,91.071 815.742,89.755 813.57,88.87C811.317,87.936 808.899,87.46 806.46,87.47C803.968,87.449 801.496,87.925 799.19,88.87C797.018,89.755 795.048,91.071 793.4,92.74C791.797,94.377 790.5,96.287 789.57,98.38C788.627,100.553 788.15,102.901 788.17,105.27Z" style="fill-rule:nonzero;"></path>
+    <path d="M871.5,65.81L899.8,65.81L899.8,75.87C903.653,71.203 907.56,68.083 911.52,66.51C915.963,64.824 920.689,64.009 925.44,64.11C930.397,63.979 935.327,64.902 939.9,66.82C943.847,68.569 947.348,71.188 950.14,74.48C952.386,77.071 953.993,80.154 954.83,83.48C955.712,87.18 956.132,90.976 956.08,94.78L956.08,145.2L927.79,145.2L927.79,105.12C927.859,101.925 927.57,98.731 926.93,95.6C926.494,93.424 925.454,91.413 923.93,89.8C922.747,88.603 921.297,87.702 919.7,87.17C918.086,86.642 916.398,86.378 914.7,86.39C909.913,86.39 906.247,87.81 903.7,90.65C901.153,93.49 899.877,97.537 899.87,102.79L899.87,145.2L871.5,145.2L871.5,65.81Z" style="fill-rule:nonzero;"></path>
+    <path d="M1006.9,89.18L1006.9,145.18L978.6,145.18L978.6,89.18L969.22,89.18L969.22,65.81L978.6,65.81L978.6,42L1006.9,42L1006.9,65.81L1023,65.81L1023,89.18L1006.9,89.18Z" style="fill-rule:nonzero;"></path>
+    <path id="Segment-1" d="M118,1C144.665,27.253 155.154,65.966 145.39,102.09C140.56,119.869 131.109,136.056 118,149L43.18,75L118,1Z" style="fill:rgb(68,180,228);"></path>
+    <rect id="Rectangle" x="1" y="1" width="31.57" height="148"></rect>
+</svg>
\ No newline at end of file
diff --git a/site/static/logos/sensetime.png b/site/static/logos/sensetime.png
new file mode 100644
index 000000000..d8fb771ad
Binary files /dev/null and b/site/static/logos/sensetime.png differ


Test patch:
diff --git a/internal/gatewayapi/testdata/envoyextensionpolicy-with-extproc-with-mixed-backendrefs.in.yaml b/internal/gatewayapi/testdata/envoyextensionpolicy-with-extproc-with-mixed-backendrefs.in.yaml
new file mode 100644
index 000000000..503a5cc14
--- /dev/null
+++ b/internal/gatewayapi/testdata/envoyextensionpolicy-with-extproc-with-mixed-backendrefs.in.yaml
@@ -0,0 +1,92 @@
+gateways:
+- apiVersion: gateway.networking.k8s.io/v1
+  kind: Gateway
+  metadata:
+    namespace: default
+    name: gateway-1
+  spec:
+    gatewayClassName: envoy-gateway-class
+    listeners:
+    - name: http
+      protocol: HTTP
+      port: 80
+      allowedRoutes:
+        namespaces:
+          from: All
+httpRoutes:
+- apiVersion: gateway.networking.k8s.io/v1
+  kind: HTTPRoute
+  metadata:
+    namespace: default
+    name: httproute-1
+  spec:
+    hostnames:
+    - www.foo.com
+    parentRefs:
+    - namespace: default
+      name: gateway-1
+      sectionName: http
+    rules:
+    - matches:
+      - path:
+          value: /foo
+      backendRefs:
+      - name: service-1
+        port: 8080
+referenceGrants:
+- apiVersion: gateway.networking.k8s.io/v1alpha2
+  kind: ReferenceGrant
+  metadata:
+    namespace: envoy-gateway
+    name: referencegrant-1
+  spec:
+    from:
+    - group: gateway.envoyproxy.io
+      kind: EnvoyExtensionPolicy
+      namespace: default
+    to:
+    - group: ''
+      kind: Service
+    - group: gateway.envoyproxy.io
+      kind: Backend
+envoyExtensionPolicies:
+- apiVersion: gateway.envoyproxy.io/v1alpha1
+  kind: EnvoyExtensionPolicy
+  metadata:
+    namespace: default
+    name: policy-for-http-route
+  spec:
+    targetRef:
+      group: gateway.networking.k8s.io
+      kind: HTTPRoute
+      name: httproute-1
+    extProc:
+    - backendRefs:
+      - Name: backend-ip
+        Kind: Backend
+        Group: gateway.envoyproxy.io
+      - Name: backend-fqdn
+        Namespace: envoy-gateway
+        Kind: Backend
+        Group: gateway.envoyproxy.io
+backends:
+- apiVersion: gateway.envoyproxy.io/v1alpha1
+  kind: Backend
+  metadata:
+    name: backend-ip
+    namespace: default
+  spec:
+    endpoints:
+    - ip:
+        address: 1.1.1.1
+        port: 3001
+- apiVersion: gateway.envoyproxy.io/v1alpha1
+  kind: Backend
+  metadata:
+    name: backend-fqdn
+    namespace: envoy-gateway
+  spec:
+    endpoints:
+    - fqdn:
+        hostname: example.com
+        port: 3001
diff --git a/internal/gatewayapi/testdata/envoyextensionpolicy-with-extproc-with-mixed-backendrefs.out.yaml b/internal/gatewayapi/testdata/envoyextensionpolicy-with-extproc-with-mixed-backendrefs.out.yaml
new file mode 100644
index 000000000..6a9fcf156
--- /dev/null
+++ b/internal/gatewayapi/testdata/envoyextensionpolicy-with-extproc-with-mixed-backendrefs.out.yaml
@@ -0,0 +1,219 @@
+backends:
+- apiVersion: gateway.envoyproxy.io/v1alpha1
+  kind: Backend
+  metadata:
+    creationTimestamp: null
+    name: backend-ip
+    namespace: default
+  spec:
+    endpoints:
+    - ip:
+        address: 1.1.1.1
+        port: 3001
+  status:
+    conditions:
+    - lastTransitionTime: null
+      message: The Backend was accepted
+      reason: Accepted
+      status: "True"
+      type: Accepted
+- apiVersion: gateway.envoyproxy.io/v1alpha1
+  kind: Backend
+  metadata:
+    creationTimestamp: null
+    name: backend-fqdn
+    namespace: envoy-gateway
+  spec:
+    endpoints:
+    - fqdn:
+        hostname: example.com
+        port: 3001
+  status:
+    conditions:
+    - lastTransitionTime: null
+      message: The Backend was accepted
+      reason: Accepted
+      status: "True"
+      type: Accepted
+envoyExtensionPolicies:
+- apiVersion: gateway.envoyproxy.io/v1alpha1
+  kind: EnvoyExtensionPolicy
+  metadata:
+    creationTimestamp: null
+    name: policy-for-http-route
+    namespace: default
+  spec:
+    extProc:
+    - backendRefs:
+      - group: gateway.envoyproxy.io
+        kind: Backend
+        name: backend-ip
+      - group: gateway.envoyproxy.io
+        kind: Backend
+        name: backend-fqdn
+        namespace: envoy-gateway
+    targetRef:
+      group: gateway.networking.k8s.io
+      kind: HTTPRoute
+      name: httproute-1
+  status:
+    ancestors:
+    - ancestorRef:
+        group: gateway.networking.k8s.io
+        kind: Gateway
+        name: gateway-1
+        namespace: default
+        sectionName: http
+      conditions:
+      - lastTransitionTime: null
+        message: 'ExtProc: mixed endpoints address type for the same route destination
+          is not supported.'
+        reason: Invalid
+        status: "False"
+        type: Accepted
+      controllerName: gateway.envoyproxy.io/gatewayclass-controller
+gateways:
+- apiVersion: gateway.networking.k8s.io/v1
+  kind: Gateway
+  metadata:
+    creationTimestamp: null
+    name: gateway-1
+    namespace: default
+  spec:
+    gatewayClassName: envoy-gateway-class
+    listeners:
+    - allowedRoutes:
+        namespaces:
+          from: All
+      name: http
+      port: 80
+      protocol: HTTP
+  status:
+    listeners:
+    - attachedRoutes: 1
+      conditions:
+      - lastTransitionTime: null
+        message: Sending translated listener configuration to the data plane
+        reason: Programmed
+        status: "True"
+        type: Programmed
+      - lastTransitionTime: null
+        message: Listener has been successfully translated
+        reason: Accepted
+        status: "True"
+        type: Accepted
+      - lastTransitionTime: null
+        message: Listener references have been resolved
+        reason: ResolvedRefs
+        status: "True"
+        type: ResolvedRefs
+      name: http
+      supportedKinds:
+      - group: gateway.networking.k8s.io
+        kind: HTTPRoute
+      - group: gateway.networking.k8s.io
+        kind: GRPCRoute
+httpRoutes:
+- apiVersion: gateway.networking.k8s.io/v1
+  kind: HTTPRoute
+  metadata:
+    creationTimestamp: null
+    name: httproute-1
+    namespace: default
+  spec:
+    hostnames:
+    - www.foo.com
+    parentRefs:
+    - name: gateway-1
+      namespace: default
+      sectionName: http
+    rules:
+    - backendRefs:
+      - name: service-1
+        port: 8080
+      matches:
+      - path:
+          value: /foo
+  status:
+    parents:
+    - conditions:
+      - lastTransitionTime: null
+        message: Route is accepted
+        reason: Accepted
+        status: "True"
+        type: Accepted
+      - lastTransitionTime: null
+        message: Resolved all the Object references for the Route
+        reason: ResolvedRefs
+        status: "True"
+        type: ResolvedRefs
+      controllerName: gateway.envoyproxy.io/gatewayclass-controller
+      parentRef:
+        name: gateway-1
+        namespace: default
+        sectionName: http
+infraIR:
+  default/gateway-1:
+    proxy:
+      listeners:
+      - address: null
+        name: default/gateway-1/http
+        ports:
+        - containerPort: 10080
+          name: http-80
+          protocol: HTTP
+          servicePort: 80
+      metadata:
+        labels:
+          gateway.envoyproxy.io/owning-gateway-name: gateway-1
+          gateway.envoyproxy.io/owning-gateway-namespace: default
+      name: default/gateway-1
+xdsIR:
+  default/gateway-1:
+    accessLog:
+      json:
+      - path: /dev/stdout
+    http:
+    - address: 0.0.0.0
+      hostnames:
+      - '*'
+      isHTTP2: false
+      metadata:
+        kind: Gateway
+        name: gateway-1
+        namespace: default
+        sectionName: http
+      name: default/gateway-1/http
+      path:
+        escapedSlashesAction: UnescapeAndRedirect
+        mergeSlashes: true
+      port: 10080
+      routes:
+      - destination:
+          name: httproute/default/httproute-1/rule/0
+          settings:
+          - addressType: IP
+            endpoints:
+            - host: 7.7.7.7
+              port: 8080
+            name: httproute/default/httproute-1/rule/0/backend/0
+            protocol: HTTP
+            weight: 1
+        directResponse:
+          statusCode: 500
+        hostname: www.foo.com
+        isHTTP2: false
+        metadata:
+          kind: HTTPRoute
+          name: httproute-1
+          namespace: default
+        name: httproute/default/httproute-1/rule/0/match/0/www_foo_com
+        pathMatch:
+          distinct: false
+          name: ""
+          prefix: /foo
+    readyListener:
+      address: 0.0.0.0
+      ipFamily: IPv4
+      path: /ready
+      port: 19003
diff --git a/internal/gatewayapi/testdata/httproute-with-header-filter-invalid-headers.in.yaml b/internal/gatewayapi/testdata/httproute-with-header-filter-invalid-headers.in.yaml
index aaf5bad87..869f9122c 100644
--- a/internal/gatewayapi/testdata/httproute-with-header-filter-invalid-headers.in.yaml
+++ b/internal/gatewayapi/testdata/httproute-with-header-filter-invalid-headers.in.yaml
@@ -30,7 +30,7 @@ httpRoutes:
     rules:
     - matches:
       - path:
-          value: "/"
+          value: "/foo"
       backendRefs:
       - name: service-1
         port: 8080
@@ -42,7 +42,57 @@ httpRoutes:
             value: "some-value"
           - name: "good-header"
             value: "some-value"
-          add:
-          - name: "example/2"
+- apiVersion: gateway.networking.k8s.io/v1
+  kind: HTTPRoute
+  metadata:
+    namespace: default
+    name: httproute-2
+  spec:
+    hostnames:
+    - gateway.envoyproxy.io
+    parentRefs:
+    - namespace: envoy-gateway
+      name: gateway-1
+      sectionName: http
+    rules:
+    - matches:
+      - path:
+          value: "/bar"
+      backendRefs:
+      - name: service-1
+        port: 8080
+      filters:
+      - type: RequestHeaderModifier
+        requestHeaderModifier:
+          remove:
+          - "example/2"
+          set:
+          - name: "good-header"
+            value: "some-value"
+- apiVersion: gateway.networking.k8s.io/v1
+  kind: HTTPRoute
+  metadata:
+    namespace: default
+    name: httproute-3
+  spec:
+    hostnames:
+    - gateway.envoyproxy.io
+    parentRefs:
+    - namespace: envoy-gateway
+      name: gateway-1
+      sectionName: http
+    rules:
+    - matches:
+      - path:
+          value: "/baz"
+      backendRefs:
+      - name: service-1
+        port: 8080
+      filters:
+      - type: RequestHeaderModifier
+        requestHeaderModifier:
+          set:
+          - name: "host"
+            value: "example.com"
+          - name: "good-header"
             value: "some-value"
-
diff --git a/internal/gatewayapi/testdata/httproute-with-header-filter-invalid-headers.out.yaml b/internal/gatewayapi/testdata/httproute-with-header-filter-invalid-headers.out.yaml
index 8e4e0fff0..2c2f5cb82 100644
--- a/internal/gatewayapi/testdata/httproute-with-header-filter-invalid-headers.out.yaml
+++ b/internal/gatewayapi/testdata/httproute-with-header-filter-invalid-headers.out.yaml
@@ -17,7 +17,7 @@ gateways:
       protocol: HTTP
   status:
     listeners:
-    - attachedRoutes: 1
+    - attachedRoutes: 3
       conditions:
       - lastTransitionTime: null
         message: Sending translated listener configuration to the data plane
@@ -60,9 +60,6 @@ httpRoutes:
         port: 8080
       filters:
       - requestHeaderModifier:
-          add:
-          - name: example/2
-            value: some-value
           set:
           - name: example:1
             value: some-value
@@ -71,13 +68,109 @@ httpRoutes:
         type: RequestHeaderModifier
       matches:
       - path:
-          value: /
+          value: /foo
+  status:
+    parents:
+    - conditions:
+      - lastTransitionTime: null
+        message: 'Header: "example:1". The RequestHeaderModifier filter cannot set
+          the Host header or headers with a ''/'' or '':'' character in them. To modify
+          the Host header use the URLRewrite or the HTTPRouteFilter filter.'
+        reason: UnsupportedValue
+        status: "False"
+        type: Accepted
+      - lastTransitionTime: null
+        message: Resolved all the Object references for the Route
+        reason: ResolvedRefs
+        status: "True"
+        type: ResolvedRefs
+      controllerName: gateway.envoyproxy.io/gatewayclass-controller
+      parentRef:
+        name: gateway-1
+        namespace: envoy-gateway
+        sectionName: http
+- apiVersion: gateway.networking.k8s.io/v1
+  kind: HTTPRoute
+  metadata:
+    creationTimestamp: null
+    name: httproute-2
+    namespace: default
+  spec:
+    hostnames:
+    - gateway.envoyproxy.io
+    parentRefs:
+    - name: gateway-1
+      namespace: envoy-gateway
+      sectionName: http
+    rules:
+    - backendRefs:
+      - name: service-1
+        port: 8080
+      filters:
+      - requestHeaderModifier:
+          remove:
+          - example/2
+          set:
+          - name: good-header
+            value: some-value
+        type: RequestHeaderModifier
+      matches:
+      - path:
+          value: /bar
+  status:
+    parents:
+    - conditions:
+      - lastTransitionTime: null
+        message: 'Header: "example/2". The RequestHeaderModifier filter cannot remove
+          the Host header or headers with a ''/'' or '':'' character in them.'
+        reason: UnsupportedValue
+        status: "False"
+        type: Accepted
+      - lastTransitionTime: null
+        message: Resolved all the Object references for the Route
+        reason: ResolvedRefs
+        status: "True"
+        type: ResolvedRefs
+      controllerName: gateway.envoyproxy.io/gatewayclass-controller
+      parentRef:
+        name: gateway-1
+        namespace: envoy-gateway
+        sectionName: http
+- apiVersion: gateway.networking.k8s.io/v1
+  kind: HTTPRoute
+  metadata:
+    creationTimestamp: null
+    name: httproute-3
+    namespace: default
+  spec:
+    hostnames:
+    - gateway.envoyproxy.io
+    parentRefs:
+    - name: gateway-1
+      namespace: envoy-gateway
+      sectionName: http
+    rules:
+    - backendRefs:
+      - name: service-1
+        port: 8080
+      filters:
+      - requestHeaderModifier:
+          set:
+          - name: host
+            value: example.com
+          - name: good-header
+            value: some-value
+        type: RequestHeaderModifier
+      matches:
+      - path:
+          value: /baz
   status:
     parents:
     - conditions:
       - lastTransitionTime: null
-        message: 'RequestHeaderModifier Filter cannot set headers with a ''/'' or
-          '':'' character in them. Header: ''example:1'''
+        message: 'Header: "host". The RequestHeaderModifier filter cannot set the
+          Host header or headers with a ''/'' or '':'' character in them. To modify
+          the Host header use the URLRewrite or the HTTPRouteFilter filter.'
         reason: UnsupportedValue
         status: "False"
         type: Accepted
diff --git a/internal/gatewayapi/testdata/httproute-with-invalid-backend-ref-invalid-mixed-kind.in.yaml b/internal/gatewayapi/testdata/httproute-with-invalid-backend-ref-invalid-mixed-kind.in.yaml
new file mode 100644
index 000000000..569b79921
--- /dev/null
+++ b/internal/gatewayapi/testdata/httproute-with-invalid-backend-ref-invalid-mixed-kind.in.yaml
@@ -0,0 +1,49 @@
+gateways:
+  - apiVersion: gateway.networking.k8s.io/v1
+    kind: Gateway
+    metadata:
+      namespace: envoy-gateway
+      name: gateway-1
+    spec:
+      gatewayClassName: envoy-gateway-class
+      listeners:
+        - name: http
+          protocol: HTTP
+          port: 80
+          allowedRoutes:
+            namespaces:
+              from: All
+backends:
+  - apiVersion: gateway.envoyproxy.io/v1alpha1
+    kind: Backend
+    metadata:
+      name: backend-fqdn
+      namespace: default
+    spec:
+      endpoints:
+        - fqdn:
+            hostname: 'primary.foo.com'
+            port: 3000
+httpRoutes:
+  - apiVersion: gateway.networking.k8s.io/v1
+    kind: HTTPRoute
+    metadata:
+      namespace: default
+      name: httproute-1
+    spec:
+      parentRefs:
+        - namespace: envoy-gateway
+          name: gateway-1
+      rules:
+        - matches:
+            - path:
+                type: Exact
+                value: "/exact"
+          backendRefs:
+            - name: service-1
+              kind: Service
+              port: 8080
+            - name: backend-fqdn
+              kind: Backend
+              group: gateway.envoyproxy.io
+              port: 3000
diff --git a/internal/gatewayapi/testdata/httproute-with-invalid-backend-ref-invalid-mixed-kind.out.yaml b/internal/gatewayapi/testdata/httproute-with-invalid-backend-ref-invalid-mixed-kind.out.yaml
new file mode 100644
index 000000000..aca7b9e65
--- /dev/null
+++ b/internal/gatewayapi/testdata/httproute-with-invalid-backend-ref-invalid-mixed-kind.out.yaml
@@ -0,0 +1,171 @@
+backends:
+- apiVersion: gateway.envoyproxy.io/v1alpha1
+  kind: Backend
+  metadata:
+    creationTimestamp: null
+    name: backend-fqdn
+    namespace: default
+  spec:
+    endpoints:
+    - fqdn:
+        hostname: primary.foo.com
+        port: 3000
+  status:
+    conditions:
+    - lastTransitionTime: null
+      message: The Backend was accepted
+      reason: Accepted
+      status: "True"
+      type: Accepted
+gateways:
+- apiVersion: gateway.networking.k8s.io/v1
+  kind: Gateway
+  metadata:
+    creationTimestamp: null
+    name: gateway-1
+    namespace: envoy-gateway
+  spec:
+    gatewayClassName: envoy-gateway-class
+    listeners:
+    - allowedRoutes:
+        namespaces:
+          from: All
+      name: http
+      port: 80
+      protocol: HTTP
+  status:
+    listeners:
+    - attachedRoutes: 1
+      conditions:
+      - lastTransitionTime: null
+        message: Sending translated listener configuration to the data plane
+        reason: Programmed
+        status: "True"
+        type: Programmed
+      - lastTransitionTime: null
+        message: Listener has been successfully translated
+        reason: Accepted
+        status: "True"
+        type: Accepted
+      - lastTransitionTime: null
+        message: Listener references have been resolved
+        reason: ResolvedRefs
+        status: "True"
+        type: ResolvedRefs
+      name: http
+      supportedKinds:
+      - group: gateway.networking.k8s.io
+        kind: HTTPRoute
+      - group: gateway.networking.k8s.io
+        kind: GRPCRoute
+httpRoutes:
+- apiVersion: gateway.networking.k8s.io/v1
+  kind: HTTPRoute
+  metadata:
+    creationTimestamp: null
+    name: httproute-1
+    namespace: default
+  spec:
+    parentRefs:
+    - name: gateway-1
+      namespace: envoy-gateway
+    rules:
+    - backendRefs:
+      - kind: Service
+        name: service-1
+        port: 8080
+      - group: gateway.envoyproxy.io
+        kind: Backend
+        name: backend-fqdn
+        port: 3000
+      matches:
+      - path:
+          type: Exact
+          value: /exact
+  status:
+    parents:
+    - conditions:
+      - lastTransitionTime: null
+        message: Route is accepted
+        reason: Accepted
+        status: "True"
+        type: Accepted
+      - lastTransitionTime: null
+        message: Mixed endpointslice address type between backendRefs is not supported
+        reason: ResolvedRefs
+        status: "False"
+        type: ResolvedRefs
+      controllerName: gateway.envoyproxy.io/gatewayclass-controller
+      parentRef:
+        name: gateway-1
+        namespace: envoy-gateway
+infraIR:
+  envoy-gateway/gateway-1:
+    proxy:
+      listeners:
+      - address: null
+        name: envoy-gateway/gateway-1/http
+        ports:
+        - containerPort: 10080
+          name: http-80
+          protocol: HTTP
+          servicePort: 80
+      metadata:
+        labels:
+          gateway.envoyproxy.io/owning-gateway-name: gateway-1
+          gateway.envoyproxy.io/owning-gateway-namespace: envoy-gateway
+      name: envoy-gateway/gateway-1
+xdsIR:
+  envoy-gateway/gateway-1:
+    accessLog:
+      json:
+      - path: /dev/stdout
+    http:
+    - address: 0.0.0.0
+      hostnames:
+      - '*'
+      isHTTP2: false
+      metadata:
+        kind: Gateway
+        name: gateway-1
+        namespace: envoy-gateway
+        sectionName: http
+      name: envoy-gateway/gateway-1/http
+      path:
+        escapedSlashesAction: UnescapeAndRedirect
+        mergeSlashes: true
+      port: 10080
+      routes:
+      - destination:
+          name: httproute/default/httproute-1/rule/0
+          settings:
+          - addressType: IP
+            endpoints:
+            - host: 7.7.7.7
+              port: 8080
+            name: httproute/default/httproute-1/rule/0/backend/0
+            protocol: HTTP
+            weight: 1
+          - addressType: FQDN
+            endpoints:
+            - host: primary.foo.com
+              port: 3000
+            name: httproute/default/httproute-1/rule/0/backend/1
+            protocol: HTTP
+            weight: 1
+        hostname: '*'
+        isHTTP2: false
+        metadata:
+          kind: HTTPRoute
+          name: httproute-1
+          namespace: default
+        name: httproute/default/httproute-1/rule/0/match/0/*
+        pathMatch:
+          distinct: false
+          exact: /exact
+          name: ""
+    readyListener:
+      address: 0.0.0.0
+      ipFamily: IPv4
+      path: /ready
+      port: 19003
diff --git a/internal/gatewayapi/testdata/httproute-with-response-header-filter-invalid-headers.in.yaml b/internal/gatewayapi/testdata/httproute-with-response-header-filter-invalid-headers.in.yaml
index 6e1e57425..95da71440 100644
--- a/internal/gatewayapi/testdata/httproute-with-response-header-filter-invalid-headers.in.yaml
+++ b/internal/gatewayapi/testdata/httproute-with-response-header-filter-invalid-headers.in.yaml
@@ -30,7 +30,7 @@ httpRoutes:
     rules:
     - matches:
       - path:
-          value: "/"
+          value: "/foo"
       backendRefs:
       - name: service-1
         port: 8080
@@ -42,7 +42,57 @@ httpRoutes:
             value: "some-value"
           - name: "good-header"
             value: "some-value"
-          add:
-          - name: "example/2"
+- apiVersion: gateway.networking.k8s.io/v1
+  kind: HTTPRoute
+  metadata:
+    namespace: default
+    name: httproute-2
+  spec:
+    hostnames:
+    - gateway.envoyproxy.io
+    parentRefs:
+    - namespace: envoy-gateway
+      name: gateway-1
+      sectionName: http
+    rules:
+    - matches:
+      - path:
+          value: "/bar"
+      backendRefs:
+      - name: service-1
+        port: 8080
+      filters:
+      - type: ResponseHeaderModifier
+        responseHeaderModifier:
+          remove:
+          - "example/2"
+          set:
+          - name: "good-header"
+            value: "some-value"
+- apiVersion: gateway.networking.k8s.io/v1
+  kind: HTTPRoute
+  metadata:
+    namespace: default
+    name: httproute-3
+  spec:
+    hostnames:
+    - gateway.envoyproxy.io
+    parentRefs:
+    - namespace: envoy-gateway
+      name: gateway-1
+      sectionName: http
+    rules:
+    - matches:
+      - path:
+          value: "/baz"
+      backendRefs:
+      - name: service-1
+        port: 8080
+      filters:
+      - type: ResponseHeaderModifier
+        responseHeaderModifier:
+          set:
+          - name: "host"
+            value: "example.com"
+          - name: "good-header"
             value: "some-value"
-
diff --git a/internal/gatewayapi/testdata/httproute-with-response-header-filter-invalid-headers.out.yaml b/internal/gatewayapi/testdata/httproute-with-response-header-filter-invalid-headers.out.yaml
index 649cbb8e7..9e476685c 100644
--- a/internal/gatewayapi/testdata/httproute-with-response-header-filter-invalid-headers.out.yaml
+++ b/internal/gatewayapi/testdata/httproute-with-response-header-filter-invalid-headers.out.yaml
@@ -17,7 +17,7 @@ gateways:
       protocol: HTTP
   status:
     listeners:
-    - attachedRoutes: 1
+    - attachedRoutes: 3
       conditions:
       - lastTransitionTime: null
         message: Sending translated listener configuration to the data plane
@@ -60,9 +60,6 @@ httpRoutes:
         port: 8080
       filters:
       - responseHeaderModifier:
-          add:
-          - name: example/2
-            value: some-value
           set:
           - name: example:1
             value: some-value
@@ -71,13 +68,107 @@ httpRoutes:
         type: ResponseHeaderModifier
       matches:
       - path:
-          value: /
+          value: /foo
+  status:
+    parents:
+    - conditions:
+      - lastTransitionTime: null
+        message: 'Header: "example:1". The ResponseHeaderModifier filter cannot set
+          the Host header or headers with a ''/'' or '':'' character in them.'
+        reason: UnsupportedValue
+        status: "False"
+        type: Accepted
+      - lastTransitionTime: null
+        message: Resolved all the Object references for the Route
+        reason: ResolvedRefs
+        status: "True"
+        type: ResolvedRefs
+      controllerName: gateway.envoyproxy.io/gatewayclass-controller
+      parentRef:
+        name: gateway-1
+        namespace: envoy-gateway
+        sectionName: http
+- apiVersion: gateway.networking.k8s.io/v1
+  kind: HTTPRoute
+  metadata:
+    creationTimestamp: null
+    name: httproute-2
+    namespace: default
+  spec:
+    hostnames:
+    - gateway.envoyproxy.io
+    parentRefs:
+    - name: gateway-1
+      namespace: envoy-gateway
+      sectionName: http
+    rules:
+    - backendRefs:
+      - name: service-1
+        port: 8080
+      filters:
+      - responseHeaderModifier:
+          remove:
+          - example/2
+          set:
+          - name: good-header
+            value: some-value
+        type: ResponseHeaderModifier
+      matches:
+      - path:
+          value: /bar
+  status:
+    parents:
+    - conditions:
+      - lastTransitionTime: null
+        message: 'Header: "example/2". The ResponseHeaderModifier filter cannot remove
+          the Host header or headers with a ''/'' or '':'' character in them.'
+        reason: UnsupportedValue
+        status: "False"
+        type: Accepted
+      - lastTransitionTime: null
+        message: Resolved all the Object references for the Route
+        reason: ResolvedRefs
+        status: "True"
+        type: ResolvedRefs
+      controllerName: gateway.envoyproxy.io/gatewayclass-controller
+      parentRef:
+        name: gateway-1
+        namespace: envoy-gateway
+        sectionName: http
+- apiVersion: gateway.networking.k8s.io/v1
+  kind: HTTPRoute
+  metadata:
+    creationTimestamp: null
+    name: httproute-3
+    namespace: default
+  spec:
+    hostnames:
+    - gateway.envoyproxy.io
+    parentRefs:
+    - name: gateway-1
+      namespace: envoy-gateway
+      sectionName: http
+    rules:
+    - backendRefs:
+      - name: service-1
+        port: 8080
+      filters:
+      - responseHeaderModifier:
+          set:
+          - name: host
+            value: example.com
+          - name: good-header
+            value: some-value
+        type: ResponseHeaderModifier
+      matches:
+      - path:
+          value: /baz
   status:
     parents:
     - conditions:
       - lastTransitionTime: null
-        message: 'ResponseHeaderModifier Filter cannot set headers with a ''/'' or
-          '':'' character in them. Header: ''example:1'''
+        message: 'Header: "host". The ResponseHeaderModifier filter cannot set the
+          Host header or headers with a ''/'' or '':'' character in them.'
         reason: UnsupportedValue
         status: "False"
         type: Accepted
diff --git a/internal/gatewayapi/testdata/securitypolicy-with-extauth-backend.in.yaml b/internal/gatewayapi/testdata/securitypolicy-with-extauth-backend.in.yaml
index 11715e27e..a327050f5 100644
--- a/internal/gatewayapi/testdata/securitypolicy-with-extauth-backend.in.yaml
+++ b/internal/gatewayapi/testdata/securitypolicy-with-extauth-backend.in.yaml
@@ -148,9 +148,6 @@ securityPolicies:
           - header2
         grpc:
           backendRefs:
-            - name: service-2
-              kind: Service
-              port: 8080
             - name: backend-fqdn
               kind: Backend
               group: gateway.envoyproxy.io
diff --git a/internal/gatewayapi/testdata/securitypolicy-with-extauth-backend.out.yaml b/internal/gatewayapi/testdata/securitypolicy-with-extauth-backend.out.yaml
index fd2b464e2..3e48e76f8 100644
--- a/internal/gatewayapi/testdata/securitypolicy-with-extauth-backend.out.yaml
+++ b/internal/gatewayapi/testdata/securitypolicy-with-extauth-backend.out.yaml
@@ -262,9 +262,6 @@ securityPolicies:
       failOpen: true
       grpc:
         backendRefs:
-        - kind: Service
-          name: service-2
-          port: 8080
         - group: gateway.envoyproxy.io
           kind: Backend
           name: backend-fqdn
@@ -405,22 +402,15 @@ xdsIR:
           extAuth:
             failOpen: true
             grpc:
-              authority: service-2.default:8080
+              authority: primary.foo.com:3000
               destination:
                 name: securitypolicy/default/policy-for-http-route-1/extauth/0
                 settings:
-                - addressType: IP
-                  endpoints:
-                  - host: 7.7.7.7
-                    port: 8080
-                  name: securitypolicy/default/policy-for-http-route-1/extauth/0/backend/0
-                  protocol: GRPC
-                  weight: 1
                 - addressType: FQDN
                   endpoints:
                   - host: primary.foo.com
                     port: 3000
-                  name: securitypolicy/default/policy-for-http-route-1/extauth/0/backend/1
+                  name: securitypolicy/default/policy-for-http-route-1/extauth/0/backend/0
                   protocol: GRPC
                   weight: 1
             headersToExtAuth:
@@ -452,22 +442,15 @@ xdsIR:
           extAuth:
             failOpen: true
             grpc:
-              authority: service-2.default:8080
+              authority: primary.foo.com:3000
               destination:
                 name: securitypolicy/default/policy-for-http-route-1/extauth/0
                 settings:
-                - addressType: IP
-                  endpoints:
-                  - host: 7.7.7.7
-                    port: 8080
-                  name: securitypolicy/default/policy-for-http-route-1/extauth/0/backend/0
-                  protocol: GRPC
-                  weight: 1
                 - addressType: FQDN
                   endpoints:
                   - host: primary.foo.com
                     port: 3000
-                  name: securitypolicy/default/policy-for-http-route-1/extauth/0/backend/1
+                  name: securitypolicy/default/policy-for-http-route-1/extauth/0/backend/0
                   protocol: GRPC
                   weight: 1
             headersToExtAuth:
diff --git a/internal/gatewayapi/testdata/securitypolicy-with-extauth-body.in.yaml b/internal/gatewayapi/testdata/securitypolicy-with-extauth-body.in.yaml
index d45b50c88..22ec1502d 100644
--- a/internal/gatewayapi/testdata/securitypolicy-with-extauth-body.in.yaml
+++ b/internal/gatewayapi/testdata/securitypolicy-with-extauth-body.in.yaml
@@ -103,9 +103,6 @@ securityPolicies:
           maxRequestBytes: 32768
         grpc:
           backendRefs:
-            - name: service-2
-              kind: Service
-              port: 8080
             - name: backend-fqdn
               kind: Backend
               group: gateway.envoyproxy.io
diff --git a/internal/gatewayapi/testdata/securitypolicy-with-extauth-body.out.yaml b/internal/gatewayapi/testdata/securitypolicy-with-extauth-body.out.yaml
index 411278ef9..a9777f7a8 100644
--- a/internal/gatewayapi/testdata/securitypolicy-with-extauth-body.out.yaml
+++ b/internal/gatewayapi/testdata/securitypolicy-with-extauth-body.out.yaml
@@ -171,9 +171,6 @@ securityPolicies:
       failOpen: true
       grpc:
         backendRefs:
-        - kind: Service
-          name: service-2
-          port: 8080
         - group: gateway.envoyproxy.io
           kind: Backend
           name: backend-fqdn
@@ -248,22 +245,15 @@ xdsIR:
               maxRequestBytes: 32768
             failOpen: true
             grpc:
-              authority: service-2.default:8080
+              authority: primary.foo.com:3000
               destination:
                 name: securitypolicy/default/policy-for-http-route-1/extauth/0
                 settings:
-                - addressType: IP
-                  endpoints:
-                  - host: 7.7.7.7
-                    port: 8080
-                  name: securitypolicy/default/policy-for-http-route-1/extauth/0/backend/0
-                  protocol: GRPC
-                  weight: 1
                 - addressType: FQDN
                   endpoints:
                   - host: primary.foo.com
                     port: 3000
-                  name: securitypolicy/default/policy-for-http-route-1/extauth/0/backend/1
+                  name: securitypolicy/default/policy-for-http-route-1/extauth/0/backend/0
                   protocol: GRPC
                   weight: 1
             headersToExtAuth:
@@ -297,22 +287,15 @@ xdsIR:
               maxRequestBytes: 32768
             failOpen: true
             grpc:
-              authority: service-2.default:8080
+              authority: primary.foo.com:3000
               destination:
                 name: securitypolicy/default/policy-for-http-route-1/extauth/0
                 settings:
-                - addressType: IP
-                  endpoints:
-                  - host: 7.7.7.7
-                    port: 8080
-                  name: securitypolicy/default/policy-for-http-route-1/extauth/0/backend/0
-                  protocol: GRPC
-                  weight: 1
                 - addressType: FQDN
                   endpoints:
                   - host: primary.foo.com
                     port: 3000
-                  name: securitypolicy/default/policy-for-http-route-1/extauth/0/backend/1
+                  name: securitypolicy/default/policy-for-http-route-1/extauth/0/backend/0
                   protocol: GRPC
                   weight: 1
             headersToExtAuth:
diff --git a/internal/gatewayapi/testdata/securitypolicy-with-extauth-recomputation.in.yaml b/internal/gatewayapi/testdata/securitypolicy-with-extauth-recomputation.in.yaml
index 5cab33ed6..adc601d21 100644
--- a/internal/gatewayapi/testdata/securitypolicy-with-extauth-recomputation.in.yaml
+++ b/internal/gatewayapi/testdata/securitypolicy-with-extauth-recomputation.in.yaml
@@ -102,9 +102,6 @@ securityPolicies:
           - header2
         grpc:
           backendRefs:
-            - name: service-2
-              kind: Service
-              port: 8080
             - name: backend-fqdn
               kind: Backend
               group: gateway.envoyproxy.io
diff --git a/internal/gatewayapi/testdata/securitypolicy-with-extauth-recomputation.out.yaml b/internal/gatewayapi/testdata/securitypolicy-with-extauth-recomputation.out.yaml
index 574b8f155..0e5423132 100644
--- a/internal/gatewayapi/testdata/securitypolicy-with-extauth-recomputation.out.yaml
+++ b/internal/gatewayapi/testdata/securitypolicy-with-extauth-recomputation.out.yaml
@@ -169,9 +169,6 @@ securityPolicies:
       failOpen: true
       grpc:
         backendRefs:
-        - kind: Service
-          name: service-2
-          port: 8080
         - group: gateway.envoyproxy.io
           kind: Backend
           name: backend-fqdn
@@ -245,22 +242,15 @@ xdsIR:
           extAuth:
             failOpen: true
             grpc:
-              authority: service-2.default:8080
+              authority: primary.foo.com:3000
               destination:
                 name: securitypolicy/default/policy-for-http-route-1/extauth/0
                 settings:
-                - addressType: IP
-                  endpoints:
-                  - host: 7.7.7.7
-                    port: 8080
-                  name: securitypolicy/default/policy-for-http-route-1/extauth/0/backend/0
-                  protocol: GRPC
-                  weight: 1
                 - addressType: FQDN
                   endpoints:
                   - host: primary.foo.com
                     port: 3000
-                  name: securitypolicy/default/policy-for-http-route-1/extauth/0/backend/1
+                  name: securitypolicy/default/policy-for-http-route-1/extauth/0/backend/0
                   protocol: GRPC
                   weight: 1
             headersToExtAuth:
@@ -293,22 +283,15 @@ xdsIR:
           extAuth:
             failOpen: true
             grpc:
-              authority: service-2.default:8080
+              authority: primary.foo.com:3000
               destination:
                 name: securitypolicy/default/policy-for-http-route-1/extauth/0
                 settings:
-                - addressType: IP
-                  endpoints:
-                  - host: 7.7.7.7
-                    port: 8080
-                  name: securitypolicy/default/policy-for-http-route-1/extauth/0/backend/0
-                  protocol: GRPC
-                  weight: 1
                 - addressType: FQDN
                   endpoints:
                   - host: primary.foo.com
                     port: 3000
-                  name: securitypolicy/default/policy-for-http-route-1/extauth/0/backend/1
+                  name: securitypolicy/default/policy-for-http-route-1/extauth/0/backend/0
                   protocol: GRPC
                   weight: 1
             headersToExtAuth:
diff --git a/internal/infrastructure/host/proxy_infra_test.go b/internal/infrastructure/host/proxy_infra_test.go
index 3437fe5a5..de3651da4 100644
--- a/internal/infrastructure/host/proxy_infra_test.go
+++ b/internal/infrastructure/host/proxy_infra_test.go
@@ -6,11 +6,13 @@
 package host
 
 import (
+	"bytes"
 	"context"
 	"path"
 	"testing"
 
 	"github.com/stretchr/testify/require"
+	funcE "github.com/tetratelabs/func-e/api"
 
 	egv1a1 "github.com/envoyproxy/gateway/api/v1alpha1"
 	"github.com/envoyproxy/gateway/internal/crypto"
@@ -20,7 +22,7 @@ import (
 	"github.com/envoyproxy/gateway/internal/utils/file"
 )
 
-func newMockInfra(t *testing.T, tCtx context.Context, cfg *config.Server, cleanProxy bool) *Infra {
+func newMockInfra(t *testing.T, cfg *config.Server) *Infra {
 	t.Helper()
 	homeDir := t.TempDir()
 	// Create envoy certs under home dir.
@@ -45,16 +47,13 @@ func newMockInfra(t *testing.T, tCtx context.Context, cfg *config.Server, cleanP
 		proxyContextMap: make(map[string]*proxyContext),
 		sdsConfigPath:   proxyDir,
 	}
-	if cleanProxy {
-		go infra.cleanProxy(tCtx)
-	}
 	return infra
 }
 
 func TestInfraCreateProxy(t *testing.T) {
 	cfg, err := config.New()
 	require.NoError(t, err)
-	infra := newMockInfra(t, context.Background(), cfg, true)
+	infra := newMockInfra(t, cfg)
 
 	// TODO: add more tests once it supports configurable homeDir and runDir.
 	testCases := []struct {
@@ -87,3 +86,27 @@ func TestInfraCreateProxy(t *testing.T) {
 		})
 	}
 }
+
+func TestInfra_runEnvoy_stopEnvoy(t *testing.T) {
+	tmpdir := t.TempDir()
+	// Ensures that all the required binaries are available.
+	err := funcE.Run(context.Background(), []string{"--version"}, funcE.HomeDir(tmpdir))
+	require.NoError(t, err)
+
+	i := &Infra{proxyContextMap: make(map[string]*proxyContext), HomeDir: tmpdir}
+	// Ensures that run -> stop will successfully stop the envoy and we can
+	// run it again without any issues.
+	for range 5 {
+		args := []string{
+			"--config-yaml",
+			"admin: {address: {socket_address: {address: '127.0.0.1', port_value: 9901}}}",
+		}
+		out := &bytes.Buffer{}
+		i.runEnvoy(context.Background(), out, "test", args)
+		require.Len(t, i.proxyContextMap, 1)
+		i.stopEnvoy("test")
+		require.Empty(t, i.proxyContextMap)
+		// If the cleanup didn't work, the error due to "address already in use" will be tried to be written to the nil logger,
+		// which will panic.
+	}
+}
diff --git a/internal/infrastructure/kubernetes/proxy/testdata/daemonsets/component-level.yaml b/internal/infrastructure/kubernetes/proxy/testdata/daemonsets/component-level.yaml
index f78f2267f..fdd2b8467 100644
--- a/internal/infrastructure/kubernetes/proxy/testdata/daemonsets/component-level.yaml
+++ b/internal/infrastructure/kubernetes/proxy/testdata/daemonsets/component-level.yaml
@@ -64,6 +64,15 @@ spec:
               path: /shutdown/ready
               port: 19002
               scheme: HTTP
+        livenessProbe:
+          failureThreshold: 3
+          httpGet:
+            path: /ready
+            port: 19003
+            scheme: HTTP
+          periodSeconds: 10
+          successThreshold: 1
+          timeoutSeconds: 1
         name: envoy
         ports:
         - containerPort: 19001
diff --git a/internal/infrastructure/kubernetes/proxy/testdata/daemonsets/custom.yaml b/internal/infrastructure/kubernetes/proxy/testdata/daemonsets/custom.yaml
index 7aecef91a..3a9c07652 100644
--- a/internal/infrastructure/kubernetes/proxy/testdata/daemonsets/custom.yaml
+++ b/internal/infrastructure/kubernetes/proxy/testdata/daemonsets/custom.yaml
@@ -245,6 +245,15 @@ spec:
               path: /shutdown/ready
               port: 19002
               scheme: HTTP
+        livenessProbe:
+          failureThreshold: 3
+          httpGet:
+            path: /ready
+            port: 19003
+            scheme: HTTP
+          periodSeconds: 10
+          successThreshold: 1
+          timeoutSeconds: 1
         name: envoy
         ports:
         - containerPort: 19001
diff --git a/internal/infrastructure/kubernetes/proxy/testdata/daemonsets/default-env.yaml b/internal/infrastructure/kubernetes/proxy/testdata/daemonsets/default-env.yaml
index 08d4927ae..b1641d7e7 100644
--- a/internal/infrastructure/kubernetes/proxy/testdata/daemonsets/default-env.yaml
+++ b/internal/infrastructure/kubernetes/proxy/testdata/daemonsets/default-env.yaml
@@ -244,6 +244,15 @@ spec:
               path: /shutdown/ready
               port: 19002
               scheme: HTTP
+        livenessProbe:
+          failureThreshold: 3
+          httpGet:
+            path: /ready
+            port: 19003
+            scheme: HTTP
+          periodSeconds: 10
+          successThreshold: 1
+          timeoutSeconds: 1
         name: envoy
         ports:
         - containerPort: 19001
diff --git a/internal/infrastructure/kubernetes/proxy/testdata/daemonsets/default.yaml b/internal/infrastructure/kubernetes/proxy/testdata/daemonsets/default.yaml
index 4ad7ab1c5..fc3b23398 100644
--- a/internal/infrastructure/kubernetes/proxy/testdata/daemonsets/default.yaml
+++ b/internal/infrastructure/kubernetes/proxy/testdata/daemonsets/default.yaml
@@ -229,6 +229,15 @@ spec:
               path: /shutdown/ready
               port: 19002
               scheme: HTTP
+        livenessProbe:
+          failureThreshold: 3
+          httpGet:
+            path: /ready
+            port: 19003
+            scheme: HTTP
+          periodSeconds: 10
+          successThreshold: 1
+          timeoutSeconds: 1
         name: envoy
         ports:
         - containerPort: 19001
diff --git a/internal/infrastructure/kubernetes/proxy/testdata/daemonsets/disable-prometheus.yaml b/internal/infrastructure/kubernetes/proxy/testdata/daemonsets/disable-prometheus.yaml
index a482ba998..51e3a64c0 100644
--- a/internal/infrastructure/kubernetes/proxy/testdata/daemonsets/disable-prometheus.yaml
+++ b/internal/infrastructure/kubernetes/proxy/testdata/daemonsets/disable-prometheus.yaml
@@ -178,6 +178,15 @@ spec:
               path: /shutdown/ready
               port: 19002
               scheme: HTTP
+        livenessProbe:
+          failureThreshold: 3
+          httpGet:
+            path: /ready
+            port: 19003
+            scheme: HTTP
+          periodSeconds: 10
+          successThreshold: 1
+          timeoutSeconds: 1
         name: envoy
         ports:
         - containerPort: 19003
diff --git a/internal/infrastructure/kubernetes/proxy/testdata/daemonsets/extension-env.yaml b/internal/infrastructure/kubernetes/proxy/testdata/daemonsets/extension-env.yaml
index 5a6edc87b..666751ca1 100644
--- a/internal/infrastructure/kubernetes/proxy/testdata/daemonsets/extension-env.yaml
+++ b/internal/infrastructure/kubernetes/proxy/testdata/daemonsets/extension-env.yaml
@@ -248,6 +248,15 @@ spec:
               path: /shutdown/ready
               port: 19002
               scheme: HTTP
+        livenessProbe:
+          failureThreshold: 3
+          httpGet:
+            path: /ready
+            port: 19003
+            scheme: HTTP
+          periodSeconds: 10
+          successThreshold: 1
+          timeoutSeconds: 1
         name: envoy
         ports:
         - containerPort: 19001
diff --git a/internal/infrastructure/kubernetes/proxy/testdata/daemonsets/override-labels-and-annotations.yaml b/internal/infrastructure/kubernetes/proxy/testdata/daemonsets/override-labels-and-annotations.yaml
index 5a7a1f558..a1e3310af 100644
--- a/internal/infrastructure/kubernetes/proxy/testdata/daemonsets/override-labels-and-annotations.yaml
+++ b/internal/infrastructure/kubernetes/proxy/testdata/daemonsets/override-labels-and-annotations.yaml
@@ -238,6 +238,15 @@ spec:
               path: /shutdown/ready
               port: 19002
               scheme: HTTP
+        livenessProbe:
+          failureThreshold: 3
+          httpGet:
+            path: /ready
+            port: 19003
+            scheme: HTTP
+          periodSeconds: 10
+          successThreshold: 1
+          timeoutSeconds: 1
         name: envoy
         ports:
         - containerPort: 19001
diff --git a/internal/infrastructure/kubernetes/proxy/testdata/daemonsets/patch-daemonset.yaml b/internal/infrastructure/kubernetes/proxy/testdata/daemonsets/patch-daemonset.yaml
index 9ce5c762e..82166f36e 100644
--- a/internal/infrastructure/kubernetes/proxy/testdata/daemonsets/patch-daemonset.yaml
+++ b/internal/infrastructure/kubernetes/proxy/testdata/daemonsets/patch-daemonset.yaml
@@ -229,6 +229,15 @@ spec:
               path: /shutdown/ready
               port: 19002
               scheme: HTTP
+        livenessProbe:
+          failureThreshold: 3
+          httpGet:
+            path: /ready
+            port: 19003
+            scheme: HTTP
+          periodSeconds: 10
+          successThreshold: 1
+          timeoutSeconds: 1
         name: envoy
         ports:
         - containerPort: 19001
diff --git a/internal/infrastructure/kubernetes/proxy/testdata/daemonsets/shutdown-manager.yaml b/internal/infrastructure/kubernetes/proxy/testdata/daemonsets/shutdown-manager.yaml
index 13fda24ac..0c725c0c4 100644
--- a/internal/infrastructure/kubernetes/proxy/testdata/daemonsets/shutdown-manager.yaml
+++ b/internal/infrastructure/kubernetes/proxy/testdata/daemonsets/shutdown-manager.yaml
@@ -229,6 +229,15 @@ spec:
               path: /shutdown/ready
               port: 19002
               scheme: HTTP
+        livenessProbe:
+          failureThreshold: 3
+          httpGet:
+            path: /ready
+            port: 19003
+            scheme: HTTP
+          periodSeconds: 10
+          successThreshold: 1
+          timeoutSeconds: 1
         name: envoy
         ports:
         - containerPort: 19001
diff --git a/internal/infrastructure/kubernetes/proxy/testdata/daemonsets/volumes.yaml b/internal/infrastructure/kubernetes/proxy/testdata/daemonsets/volumes.yaml
index 7d34a8482..d5289cbfb 100644
--- a/internal/infrastructure/kubernetes/proxy/testdata/daemonsets/volumes.yaml
+++ b/internal/infrastructure/kubernetes/proxy/testdata/daemonsets/volumes.yaml
@@ -248,6 +248,15 @@ spec:
               path: /shutdown/ready
               port: 19002
               scheme: HTTP
+        livenessProbe:
+          failureThreshold: 3
+          httpGet:
+            path: /ready
+            port: 19003
+            scheme: HTTP
+          periodSeconds: 10
+          successThreshold: 1
+          timeoutSeconds: 1
         name: envoy
         ports:
         - containerPort: 19001
diff --git a/internal/infrastructure/kubernetes/proxy/testdata/daemonsets/with-annotations.yaml b/internal/infrastructure/kubernetes/proxy/testdata/daemonsets/with-annotations.yaml
index be0da3b4d..c79622ddf 100644
--- a/internal/infrastructure/kubernetes/proxy/testdata/daemonsets/with-annotations.yaml
+++ b/internal/infrastructure/kubernetes/proxy/testdata/daemonsets/with-annotations.yaml
@@ -234,6 +234,15 @@ spec:
               path: /shutdown/ready
               port: 19002
               scheme: HTTP
+        livenessProbe:
+          failureThreshold: 3
+          httpGet:
+            path: /ready
+            port: 19003
+            scheme: HTTP
+          periodSeconds: 10
+          successThreshold: 1
+          timeoutSeconds: 1
         name: envoy
         ports:
         - containerPort: 19001
diff --git a/internal/infrastructure/kubernetes/proxy/testdata/daemonsets/with-concurrency.yaml b/internal/infrastructure/kubernetes/proxy/testdata/daemonsets/with-concurrency.yaml
index 7fbf478e1..bfe36519b 100644
--- a/internal/infrastructure/kubernetes/proxy/testdata/daemonsets/with-concurrency.yaml
+++ b/internal/infrastructure/kubernetes/proxy/testdata/daemonsets/with-concurrency.yaml
@@ -64,6 +64,15 @@ spec:
               path: /shutdown/ready
               port: 19002
               scheme: HTTP
+        livenessProbe:
+          failureThreshold: 3
+          httpGet:
+            path: /ready
+            port: 19003
+            scheme: HTTP
+          periodSeconds: 10
+          successThreshold: 1
+          timeoutSeconds: 1
         name: envoy
         ports:
         - containerPort: 19001
diff --git a/internal/infrastructure/kubernetes/proxy/testdata/daemonsets/with-extra-args.yaml b/internal/infrastructure/kubernetes/proxy/testdata/daemonsets/with-extra-args.yaml
index e6dad211f..015f9f138 100644
--- a/internal/infrastructure/kubernetes/proxy/testdata/daemonsets/with-extra-args.yaml
+++ b/internal/infrastructure/kubernetes/proxy/testdata/daemonsets/with-extra-args.yaml
@@ -231,6 +231,15 @@ spec:
               path: /shutdown/ready
               port: 19002
               scheme: HTTP
+        livenessProbe:
+          failureThreshold: 3
+          httpGet:
+            path: /ready
+            port: 19003
+            scheme: HTTP
+          periodSeconds: 10
+          successThreshold: 1
+          timeoutSeconds: 1
         name: envoy
         ports:
         - containerPort: 19001
diff --git a/internal/infrastructure/kubernetes/proxy/testdata/daemonsets/with-image-pull-secrets.yaml b/internal/infrastructure/kubernetes/proxy/testdata/daemonsets/with-image-pull-secrets.yaml
index 2b3013b8b..91abeb07c 100644
--- a/internal/infrastructure/kubernetes/proxy/testdata/daemonsets/with-image-pull-secrets.yaml
+++ b/internal/infrastructure/kubernetes/proxy/testdata/daemonsets/with-image-pull-secrets.yaml
@@ -229,6 +229,15 @@ spec:
               path: /shutdown/ready
               port: 19002
               scheme: HTTP
+        livenessProbe:
+          failureThreshold: 3
+          httpGet:
+            path: /ready
+            port: 19003
+            scheme: HTTP
+          periodSeconds: 10
+          successThreshold: 1
+          timeoutSeconds: 1
         name: envoy
         ports:
         - containerPort: 19001
diff --git a/internal/infrastructure/kubernetes/proxy/testdata/daemonsets/with-name.yaml b/internal/infrastructure/kubernetes/proxy/testdata/daemonsets/with-name.yaml
index 3eb45346e..d671ae638 100644
--- a/internal/infrastructure/kubernetes/proxy/testdata/daemonsets/with-name.yaml
+++ b/internal/infrastructure/kubernetes/proxy/testdata/daemonsets/with-name.yaml
@@ -229,6 +229,15 @@ spec:
               path: /shutdown/ready
               port: 19002
               scheme: HTTP
+        livenessProbe:
+          failureThreshold: 3
+          httpGet:
+            path: /ready
+            port: 19003
+            scheme: HTTP
+          periodSeconds: 10
+          successThreshold: 1
+          timeoutSeconds: 1
         name: envoy
         ports:
         - containerPort: 19001
diff --git a/internal/infrastructure/kubernetes/proxy/testdata/daemonsets/with-node-selector.yaml b/internal/infrastructure/kubernetes/proxy/testdata/daemonsets/with-node-selector.yaml
index e3e5560bd..87161f5ea 100644
--- a/internal/infrastructure/kubernetes/proxy/testdata/daemonsets/with-node-selector.yaml
+++ b/internal/infrastructure/kubernetes/proxy/testdata/daemonsets/with-node-selector.yaml
@@ -229,6 +229,15 @@ spec:
               path: /shutdown/ready
               port: 19002
               scheme: HTTP
+        livenessProbe:
+          failureThreshold: 3
+          httpGet:
+            path: /ready
+            port: 19003
+            scheme: HTTP
+          periodSeconds: 10
+          successThreshold: 1
+          timeoutSeconds: 1
         name: envoy
         ports:
         - containerPort: 19001
diff --git a/internal/infrastructure/kubernetes/proxy/testdata/daemonsets/with-topology-spread-constraints.yaml b/internal/infrastructure/kubernetes/proxy/testdata/daemonsets/with-topology-spread-constraints.yaml
index 55a712194..1775cc739 100644
--- a/internal/infrastructure/kubernetes/proxy/testdata/daemonsets/with-topology-spread-constraints.yaml
+++ b/internal/infrastructure/kubernetes/proxy/testdata/daemonsets/with-topology-spread-constraints.yaml
@@ -229,6 +229,15 @@ spec:
               path: /shutdown/ready
               port: 19002
               scheme: HTTP
+        livenessProbe:
+          failureThreshold: 3
+          httpGet:
+            path: /ready
+            port: 19003
+            scheme: HTTP
+          periodSeconds: 10
+          successThreshold: 1
+          timeoutSeconds: 1
         name: envoy
         ports:
         - containerPort: 19001
diff --git a/internal/infrastructure/kubernetes/proxy/testdata/deployments/bootstrap.yaml b/internal/infrastructure/kubernetes/proxy/testdata/deployments/bootstrap.yaml
index 3fd56466d..87f81b63e 100644
--- a/internal/infrastructure/kubernetes/proxy/testdata/deployments/bootstrap.yaml
+++ b/internal/infrastructure/kubernetes/proxy/testdata/deployments/bootstrap.yaml
@@ -67,6 +67,15 @@ spec:
               path: /shutdown/ready
               port: 19002
               scheme: HTTP
+        livenessProbe:
+          failureThreshold: 3
+          httpGet:
+            path: /ready
+            port: 19003
+            scheme: HTTP
+          periodSeconds: 10
+          successThreshold: 1
+          timeoutSeconds: 1
         name: envoy
         ports:
         - containerPort: 19001
diff --git a/internal/infrastructure/kubernetes/proxy/testdata/deployments/component-level.yaml b/internal/infrastructure/kubernetes/proxy/testdata/deployments/component-level.yaml
index 8a6c97405..7b7d7f175 100644
--- a/internal/infrastructure/kubernetes/proxy/testdata/deployments/component-level.yaml
+++ b/internal/infrastructure/kubernetes/proxy/testdata/deployments/component-level.yaml
@@ -68,6 +68,15 @@ spec:
               path: /shutdown/ready
               port: 19002
               scheme: HTTP
+        livenessProbe:
+          failureThreshold: 3
+          httpGet:
+            path: /ready
+            port: 19003
+            scheme: HTTP
+          periodSeconds: 10
+          successThreshold: 1
+          timeoutSeconds: 1
         name: envoy
         ports:
         - containerPort: 19001
diff --git a/internal/infrastructure/kubernetes/proxy/testdata/deployments/custom.yaml b/internal/infrastructure/kubernetes/proxy/testdata/deployments/custom.yaml
index 6cbe5ce6b..b28b922a6 100644
--- a/internal/infrastructure/kubernetes/proxy/testdata/deployments/custom.yaml
+++ b/internal/infrastructure/kubernetes/proxy/testdata/deployments/custom.yaml
@@ -250,6 +250,15 @@ spec:
               path: /shutdown/ready
               port: 19002
               scheme: HTTP
+        livenessProbe:
+          failureThreshold: 3
+          httpGet:
+            path: /ready
+            port: 19003
+            scheme: HTTP
+          periodSeconds: 10
+          successThreshold: 1
+          timeoutSeconds: 1
         name: envoy
         ports:
         - containerPort: 19001
diff --git a/internal/infrastructure/kubernetes/proxy/testdata/deployments/custom_with_initcontainers.yaml b/internal/infrastructure/kubernetes/proxy/testdata/deployments/custom_with_initcontainers.yaml
index 5b2d77d97..ec6b037eb 100644
--- a/internal/infrastructure/kubernetes/proxy/testdata/deployments/custom_with_initcontainers.yaml
+++ b/internal/infrastructure/kubernetes/proxy/testdata/deployments/custom_with_initcontainers.yaml
@@ -250,6 +250,15 @@ spec:
               path: /shutdown/ready
               port: 19002
               scheme: HTTP
+        livenessProbe:
+          failureThreshold: 3
+          httpGet:
+            path: /ready
+            port: 19003
+            scheme: HTTP
+          periodSeconds: 10
+          successThreshold: 1
+          timeoutSeconds: 1
         name: envoy
         ports:
         - containerPort: 19001
diff --git a/internal/infrastructure/kubernetes/proxy/testdata/deployments/default-env.yaml b/internal/infrastructure/kubernetes/proxy/testdata/deployments/default-env.yaml
index e7ab25e16..77e2ecb19 100644
--- a/internal/infrastructure/kubernetes/proxy/testdata/deployments/default-env.yaml
+++ b/internal/infrastructure/kubernetes/proxy/testdata/deployments/default-env.yaml
@@ -249,6 +249,15 @@ spec:
               path: /shutdown/ready
               port: 19002
               scheme: HTTP
+        livenessProbe:
+          failureThreshold: 3
+          httpGet:
+            path: /ready
+            port: 19003
+            scheme: HTTP
+          periodSeconds: 10
+          successThreshold: 1
+          timeoutSeconds: 1
         name: envoy
         ports:
         - containerPort: 19001
diff --git a/internal/infrastructure/kubernetes/proxy/testdata/deployments/default.yaml b/internal/infrastructure/kubernetes/proxy/testdata/deployments/default.yaml
index f89ea3fbc..6431d027b 100644
--- a/internal/infrastructure/kubernetes/proxy/testdata/deployments/default.yaml
+++ b/internal/infrastructure/kubernetes/proxy/testdata/deployments/default.yaml
@@ -233,6 +233,15 @@ spec:
               path: /shutdown/ready
               port: 19002
               scheme: HTTP
+        livenessProbe:
+          failureThreshold: 3
+          httpGet:
+            path: /ready
+            port: 19003
+            scheme: HTTP
+          periodSeconds: 10
+          successThreshold: 1
+          timeoutSeconds: 1
         name: envoy
         ports:
         - containerPort: 19001
diff --git a/internal/infrastructure/kubernetes/proxy/testdata/deployments/disable-prometheus.yaml b/internal/infrastructure/kubernetes/proxy/testdata/deployments/disable-prometheus.yaml
index 5f4ed7dfc..59f89179c 100644
--- a/internal/infrastructure/kubernetes/proxy/testdata/deployments/disable-prometheus.yaml
+++ b/internal/infrastructure/kubernetes/proxy/testdata/deployments/disable-prometheus.yaml
@@ -182,6 +182,15 @@ spec:
               path: /shutdown/ready
               port: 19002
               scheme: HTTP
+        livenessProbe:
+          failureThreshold: 3
+          httpGet:
+            path: /ready
+            port: 19003
+            scheme: HTTP
+          periodSeconds: 10
+          successThreshold: 1
+          timeoutSeconds: 1
         name: envoy
         ports:
         - containerPort: 19003
diff --git a/internal/infrastructure/kubernetes/proxy/testdata/deployments/dual-stack.yaml b/internal/infrastructure/kubernetes/proxy/testdata/deployments/dual-stack.yaml
index 189b24168..234038cb4 100644
--- a/internal/infrastructure/kubernetes/proxy/testdata/deployments/dual-stack.yaml
+++ b/internal/infrastructure/kubernetes/proxy/testdata/deployments/dual-stack.yaml
@@ -234,6 +234,15 @@ spec:
               path: /shutdown/ready
               port: 19002
               scheme: HTTP
+        livenessProbe:
+          failureThreshold: 3
+          httpGet:
+            path: /ready
+            port: 19003
+            scheme: HTTP
+          periodSeconds: 10
+          successThreshold: 1
+          timeoutSeconds: 1
         name: envoy
         ports:
         - containerPort: 19001
diff --git a/internal/infrastructure/kubernetes/proxy/testdata/deployments/extension-env.yaml b/internal/infrastructure/kubernetes/proxy/testdata/deployments/extension-env.yaml
index 2eac3726f..da510520b 100644
--- a/internal/infrastructure/kubernetes/proxy/testdata/deployments/extension-env.yaml
+++ b/internal/infrastructure/kubernetes/proxy/testdata/deployments/extension-env.yaml
@@ -253,6 +253,15 @@ spec:
               path: /shutdown/ready
               port: 19002
               scheme: HTTP
+        livenessProbe:
+          failureThreshold: 3
+          httpGet:
+            path: /ready
+            port: 19003
+            scheme: HTTP
+          periodSeconds: 10
+          successThreshold: 1
+          timeoutSeconds: 1
         name: envoy
         ports:
         - containerPort: 19001
diff --git a/internal/infrastructure/kubernetes/proxy/testdata/deployments/ipv6.yaml b/internal/infrastructure/kubernetes/proxy/testdata/deployments/ipv6.yaml
index a22f61810..5095a964b 100644
--- a/internal/infrastructure/kubernetes/proxy/testdata/deployments/ipv6.yaml
+++ b/internal/infrastructure/kubernetes/proxy/testdata/deployments/ipv6.yaml
@@ -234,6 +234,15 @@ spec:
               path: /shutdown/ready
               port: 19002
               scheme: HTTP
+        livenessProbe:
+          failureThreshold: 3
+          httpGet:
+            path: /ready
+            port: 19003
+            scheme: HTTP
+          periodSeconds: 10
+          successThreshold: 1
+          timeoutSeconds: 1
         name: envoy
         ports:
         - containerPort: 19001
diff --git a/internal/infrastructure/kubernetes/proxy/testdata/deployments/override-labels-and-annotations.yaml b/internal/infrastructure/kubernetes/proxy/testdata/deployments/override-labels-and-annotations.yaml
index 3e7ae1078..b51f939b0 100644
--- a/internal/infrastructure/kubernetes/proxy/testdata/deployments/override-labels-and-annotations.yaml
+++ b/internal/infrastructure/kubernetes/proxy/testdata/deployments/override-labels-and-annotations.yaml
@@ -242,6 +242,15 @@ spec:
               path: /shutdown/ready
               port: 19002
               scheme: HTTP
+        livenessProbe:
+          failureThreshold: 3
+          httpGet:
+            path: /ready
+            port: 19003
+            scheme: HTTP
+          periodSeconds: 10
+          successThreshold: 1
+          timeoutSeconds: 1
         name: envoy
         ports:
         - containerPort: 19001
diff --git a/internal/infrastructure/kubernetes/proxy/testdata/deployments/patch-deployment.yaml b/internal/infrastructure/kubernetes/proxy/testdata/deployments/patch-deployment.yaml
index 643a0bf30..d786f0625 100644
--- a/internal/infrastructure/kubernetes/proxy/testdata/deployments/patch-deployment.yaml
+++ b/internal/infrastructure/kubernetes/proxy/testdata/deployments/patch-deployment.yaml
@@ -233,6 +233,15 @@ spec:
               path: /shutdown/ready
               port: 19002
               scheme: HTTP
+        livenessProbe:
+          failureThreshold: 3
+          httpGet:
+            path: /ready
+            port: 19003
+            scheme: HTTP
+          periodSeconds: 10
+          successThreshold: 1
+          timeoutSeconds: 1
         name: envoy
         ports:
         - containerPort: 19001
diff --git a/internal/infrastructure/kubernetes/proxy/testdata/deployments/shutdown-manager.yaml b/internal/infrastructure/kubernetes/proxy/testdata/deployments/shutdown-manager.yaml
index c6525d042..5f798bc8f 100644
--- a/internal/infrastructure/kubernetes/proxy/testdata/deployments/shutdown-manager.yaml
+++ b/internal/infrastructure/kubernetes/proxy/testdata/deployments/shutdown-manager.yaml
@@ -233,6 +233,15 @@ spec:
               path: /shutdown/ready
               port: 19002
               scheme: HTTP
+        livenessProbe:
+          failureThreshold: 3
+          httpGet:
+            path: /ready
+            port: 19003
+            scheme: HTTP
+          periodSeconds: 10
+          successThreshold: 1
+          timeoutSeconds: 1
         name: envoy
         ports:
         - containerPort: 19001
diff --git a/internal/infrastructure/kubernetes/proxy/testdata/deployments/volumes.yaml b/internal/infrastructure/kubernetes/proxy/testdata/deployments/volumes.yaml
index fcbfbfc59..ef2790f7a 100644
--- a/internal/infrastructure/kubernetes/proxy/testdata/deployments/volumes.yaml
+++ b/internal/infrastructure/kubernetes/proxy/testdata/deployments/volumes.yaml
@@ -253,6 +253,15 @@ spec:
               path: /shutdown/ready
               port: 19002
               scheme: HTTP
+        livenessProbe:
+          failureThreshold: 3
+          httpGet:
+            path: /ready
+            port: 19003
+            scheme: HTTP
+          periodSeconds: 10
+          successThreshold: 1
+          timeoutSeconds: 1
         name: envoy
         ports:
         - containerPort: 19001
diff --git a/internal/infrastructure/kubernetes/proxy/testdata/deployments/with-annotations.yaml b/internal/infrastructure/kubernetes/proxy/testdata/deployments/with-annotations.yaml
index c03353fb1..029df5fc2 100644
--- a/internal/infrastructure/kubernetes/proxy/testdata/deployments/with-annotations.yaml
+++ b/internal/infrastructure/kubernetes/proxy/testdata/deployments/with-annotations.yaml
@@ -238,6 +238,15 @@ spec:
               path: /shutdown/ready
               port: 19002
               scheme: HTTP
+        livenessProbe:
+          failureThreshold: 3
+          httpGet:
+            path: /ready
+            port: 19003
+            scheme: HTTP
+          periodSeconds: 10
+          successThreshold: 1
+          timeoutSeconds: 1
         name: envoy
         ports:
         - containerPort: 19001
diff --git a/internal/infrastructure/kubernetes/proxy/testdata/deployments/with-concurrency.yaml b/internal/infrastructure/kubernetes/proxy/testdata/deployments/with-concurrency.yaml
index 3cdcc8f4d..03d7a4811 100644
--- a/internal/infrastructure/kubernetes/proxy/testdata/deployments/with-concurrency.yaml
+++ b/internal/infrastructure/kubernetes/proxy/testdata/deployments/with-concurrency.yaml
@@ -68,6 +68,15 @@ spec:
               path: /shutdown/ready
               port: 19002
               scheme: HTTP
+        livenessProbe:
+          failureThreshold: 3
+          httpGet:
+            path: /ready
+            port: 19003
+            scheme: HTTP
+          periodSeconds: 10
+          successThreshold: 1
+          timeoutSeconds: 1
         name: envoy
         ports:
         - containerPort: 19001
diff --git a/internal/infrastructure/kubernetes/proxy/testdata/deployments/with-empty-memory-limits.yaml b/internal/infrastructure/kubernetes/proxy/testdata/deployments/with-empty-memory-limits.yaml
index fb49502f8..55245f1ed 100644
--- a/internal/infrastructure/kubernetes/proxy/testdata/deployments/with-empty-memory-limits.yaml
+++ b/internal/infrastructure/kubernetes/proxy/testdata/deployments/with-empty-memory-limits.yaml
@@ -233,6 +233,15 @@ spec:
               path: /shutdown/ready
               port: 19002
               scheme: HTTP
+        livenessProbe:
+          failureThreshold: 3
+          httpGet:
+            path: /ready
+            port: 19003
+            scheme: HTTP
+          periodSeconds: 10
+          successThreshold: 1
+          timeoutSeconds: 1
         name: envoy
         ports:
         - containerPort: 19001
diff --git a/internal/infrastructure/kubernetes/proxy/testdata/deployments/with-extra-args.yaml b/internal/infrastructure/kubernetes/proxy/testdata/deployments/with-extra-args.yaml
index fb1c9f4f1..9dfa6343d 100644
--- a/internal/infrastructure/kubernetes/proxy/testdata/deployments/with-extra-args.yaml
+++ b/internal/infrastructure/kubernetes/proxy/testdata/deployments/with-extra-args.yaml
@@ -235,6 +235,15 @@ spec:
               path: /shutdown/ready
               port: 19002
               scheme: HTTP
+        livenessProbe:
+          failureThreshold: 3
+          httpGet:
+            path: /ready
+            port: 19003
+            scheme: HTTP
+          periodSeconds: 10
+          successThreshold: 1
+          timeoutSeconds: 1
         name: envoy
         ports:
         - containerPort: 19001
diff --git a/internal/infrastructure/kubernetes/proxy/testdata/deployments/with-image-pull-secrets.yaml b/internal/infrastructure/kubernetes/proxy/testdata/deployments/with-image-pull-secrets.yaml
index caf5d5e13..fe0a7e91a 100644
--- a/internal/infrastructure/kubernetes/proxy/testdata/deployments/with-image-pull-secrets.yaml
+++ b/internal/infrastructure/kubernetes/proxy/testdata/deployments/with-image-pull-secrets.yaml
@@ -233,6 +233,15 @@ spec:
               path: /shutdown/ready
               port: 19002
               scheme: HTTP
+        livenessProbe:
+          failureThreshold: 3
+          httpGet:
+            path: /ready
+            port: 19003
+            scheme: HTTP
+          periodSeconds: 10
+          successThreshold: 1
+          timeoutSeconds: 1
         name: envoy
         ports:
         - containerPort: 19001
diff --git a/internal/infrastructure/kubernetes/proxy/testdata/deployments/with-name.yaml b/internal/infrastructure/kubernetes/proxy/testdata/deployments/with-name.yaml
index 6f5314ca7..eb94e3eb5 100644
--- a/internal/infrastructure/kubernetes/proxy/testdata/deployments/with-name.yaml
+++ b/internal/infrastructure/kubernetes/proxy/testdata/deployments/with-name.yaml
@@ -233,6 +233,15 @@ spec:
               path: /shutdown/ready
               port: 19002
               scheme: HTTP
+        livenessProbe:
+          failureThreshold: 3
+          httpGet:
+            path: /ready
+            port: 19003
+            scheme: HTTP
+          periodSeconds: 10
+          successThreshold: 1
+          timeoutSeconds: 1
         name: envoy
         ports:
         - containerPort: 19001
diff --git a/internal/infrastructure/kubernetes/proxy/testdata/deployments/with-node-selector.yaml b/internal/infrastructure/kubernetes/proxy/testdata/deployments/with-node-selector.yaml
index 7992e0b58..273c1e4ea 100644
--- a/internal/infrastructure/kubernetes/proxy/testdata/deployments/with-node-selector.yaml
+++ b/internal/infrastructure/kubernetes/proxy/testdata/deployments/with-node-selector.yaml
@@ -233,6 +233,15 @@ spec:
               path: /shutdown/ready
               port: 19002
               scheme: HTTP
+        livenessProbe:
+          failureThreshold: 3
+          httpGet:
+            path: /ready
+            port: 19003
+            scheme: HTTP
+          periodSeconds: 10
+          successThreshold: 1
+          timeoutSeconds: 1
         name: envoy
         ports:
         - containerPort: 19001
diff --git a/internal/infrastructure/kubernetes/proxy/testdata/deployments/with-topology-spread-constraints.yaml b/internal/infrastructure/kubernetes/proxy/testdata/deployments/with-topology-spread-constraints.yaml
index c38606b38..de61c1f9a 100644
--- a/internal/infrastructure/kubernetes/proxy/testdata/deployments/with-topology-spread-constraints.yaml
+++ b/internal/infrastructure/kubernetes/proxy/testdata/deployments/with-topology-spread-constraints.yaml
@@ -233,6 +233,15 @@ spec:
               path: /shutdown/ready
               port: 19002
               scheme: HTTP
+        livenessProbe:
+          failureThreshold: 3
+          httpGet:
+            path: /ready
+            port: 19003
+            scheme: HTTP
+          periodSeconds: 10
+          successThreshold: 1
+          timeoutSeconds: 1
         name: envoy
         ports:
         - containerPort: 19001
diff --git a/internal/infrastructure/kubernetes/ratelimit/testdata/deployments/custom.yaml b/internal/infrastructure/kubernetes/ratelimit/testdata/deployments/custom.yaml
index 0c1be549e..82092844b 100644
--- a/internal/infrastructure/kubernetes/ratelimit/testdata/deployments/custom.yaml
+++ b/internal/infrastructure/kubernetes/ratelimit/testdata/deployments/custom.yaml
@@ -89,6 +89,15 @@ spec:
           value: /etc/statsd-exporter/conf.yaml
         image: custom-image
         imagePullPolicy: IfNotPresent
+        livenessProbe:
+          failureThreshold: 3
+          httpGet:
+            path: /healthcheck
+            port: 8080
+            scheme: HTTP
+          periodSeconds: 10
+          successThreshold: 1
+          timeoutSeconds: 1
         name: envoy-ratelimit
         ports:
         - containerPort: 8081
diff --git a/internal/infrastructure/kubernetes/ratelimit/testdata/deployments/default-env.yaml b/internal/infrastructure/kubernetes/ratelimit/testdata/deployments/default-env.yaml
index 0c1be549e..82092844b 100644
--- a/internal/infrastructure/kubernetes/ratelimit/testdata/deployments/default-env.yaml
+++ b/internal/infrastructure/kubernetes/ratelimit/testdata/deployments/default-env.yaml
@@ -89,6 +89,15 @@ spec:
           value: /etc/statsd-exporter/conf.yaml
         image: custom-image
         imagePullPolicy: IfNotPresent
+        livenessProbe:
+          failureThreshold: 3
+          httpGet:
+            path: /healthcheck
+            port: 8080
+            scheme: HTTP
+          periodSeconds: 10
+          successThreshold: 1
+          timeoutSeconds: 1
         name: envoy-ratelimit
         ports:
         - containerPort: 8081
diff --git a/internal/infrastructure/kubernetes/ratelimit/testdata/deployments/default.yaml b/internal/infrastructure/kubernetes/ratelimit/testdata/deployments/default.yaml
index f3b49afb4..1cc68f00a 100644
--- a/internal/infrastructure/kubernetes/ratelimit/testdata/deployments/default.yaml
+++ b/internal/infrastructure/kubernetes/ratelimit/testdata/deployments/default.yaml
@@ -88,6 +88,15 @@ spec:
           value: /etc/statsd-exporter/conf.yaml
         image: docker.io/envoyproxy/ratelimit:master
         imagePullPolicy: IfNotPresent
+        livenessProbe:
+          failureThreshold: 3
+          httpGet:
+            path: /healthcheck
+            port: 8080
+            scheme: HTTP
+          periodSeconds: 10
+          successThreshold: 1
+          timeoutSeconds: 1
         name: envoy-ratelimit
         ports:
         - containerPort: 8081
diff --git a/internal/infrastructure/kubernetes/ratelimit/testdata/deployments/disable-prometheus.yaml b/internal/infrastructure/kubernetes/ratelimit/testdata/deployments/disable-prometheus.yaml
index b579400b0..502a0dd3b 100644
--- a/internal/infrastructure/kubernetes/ratelimit/testdata/deployments/disable-prometheus.yaml
+++ b/internal/infrastructure/kubernetes/ratelimit/testdata/deployments/disable-prometheus.yaml
@@ -78,6 +78,15 @@ spec:
           value: redis.redis.svc:6379
         image: docker.io/envoyproxy/ratelimit:master
         imagePullPolicy: IfNotPresent
+        livenessProbe:
+          failureThreshold: 3
+          httpGet:
+            path: /healthcheck
+            port: 8080
+            scheme: HTTP
+          periodSeconds: 10
+          successThreshold: 1
+          timeoutSeconds: 1
         name: envoy-ratelimit
         ports:
         - containerPort: 8081
diff --git a/internal/infrastructure/kubernetes/ratelimit/testdata/deployments/enable-tracing-custom.yaml b/internal/infrastructure/kubernetes/ratelimit/testdata/deployments/enable-tracing-custom.yaml
index c8586388f..4dd13119b 100644
--- a/internal/infrastructure/kubernetes/ratelimit/testdata/deployments/enable-tracing-custom.yaml
+++ b/internal/infrastructure/kubernetes/ratelimit/testdata/deployments/enable-tracing-custom.yaml
@@ -103,6 +103,15 @@ spec:
           value: http://trace-collector.envoy-gateway-system.svc.cluster.local:4317
         image: docker.io/envoyproxy/ratelimit:master
         imagePullPolicy: IfNotPresent
+        livenessProbe:
+          failureThreshold: 3
+          httpGet:
+            path: /healthcheck
+            port: 8080
+            scheme: HTTP
+          periodSeconds: 10
+          successThreshold: 1
+          timeoutSeconds: 1
         name: envoy-ratelimit
         ports:
         - containerPort: 8081
diff --git a/internal/infrastructure/kubernetes/ratelimit/testdata/deployments/enable-tracing.yaml b/internal/infrastructure/kubernetes/ratelimit/testdata/deployments/enable-tracing.yaml
index 002ee53bd..1fa61480b 100644
--- a/internal/infrastructure/kubernetes/ratelimit/testdata/deployments/enable-tracing.yaml
+++ b/internal/infrastructure/kubernetes/ratelimit/testdata/deployments/enable-tracing.yaml
@@ -103,6 +103,15 @@ spec:
           value: http://trace-collector.envoy-gateway-system.svc.cluster.local:4318
         image: docker.io/envoyproxy/ratelimit:master
         imagePullPolicy: IfNotPresent
+        livenessProbe:
+          failureThreshold: 3
+          httpGet:
+            path: /healthcheck
+            port: 8080
+            scheme: HTTP
+          periodSeconds: 10
+          successThreshold: 1
+          timeoutSeconds: 1
         name: envoy-ratelimit
         ports:
         - containerPort: 8081
diff --git a/internal/infrastructure/kubernetes/ratelimit/testdata/deployments/extension-env.yaml b/internal/infrastructure/kubernetes/ratelimit/testdata/deployments/extension-env.yaml
index 65c68972f..2bd014620 100644
--- a/internal/infrastructure/kubernetes/ratelimit/testdata/deployments/extension-env.yaml
+++ b/internal/infrastructure/kubernetes/ratelimit/testdata/deployments/extension-env.yaml
@@ -93,6 +93,15 @@ spec:
           value: env_b_value
         image: custom-image
         imagePullPolicy: IfNotPresent
+        livenessProbe:
+          failureThreshold: 3
+          httpGet:
+            path: /healthcheck
+            port: 8080
+            scheme: HTTP
+          periodSeconds: 10
+          successThreshold: 1
+          timeoutSeconds: 1
         name: envoy-ratelimit
         ports:
         - containerPort: 8081
diff --git a/internal/infrastructure/kubernetes/ratelimit/testdata/deployments/merge-annotations.yaml b/internal/infrastructure/kubernetes/ratelimit/testdata/deployments/merge-annotations.yaml
index fc6600de0..1d7ac9f09 100644
--- a/internal/infrastructure/kubernetes/ratelimit/testdata/deployments/merge-annotations.yaml
+++ b/internal/infrastructure/kubernetes/ratelimit/testdata/deployments/merge-annotations.yaml
@@ -90,6 +90,15 @@ spec:
           value: /etc/statsd-exporter/conf.yaml
         image: docker.io/envoyproxy/ratelimit:master
         imagePullPolicy: IfNotPresent
+        livenessProbe:
+          failureThreshold: 3
+          httpGet:
+            path: /healthcheck
+            port: 8080
+            scheme: HTTP
+          periodSeconds: 10
+          successThreshold: 1
+          timeoutSeconds: 1
         name: envoy-ratelimit
         ports:
         - containerPort: 8081
diff --git a/internal/infrastructure/kubernetes/ratelimit/testdata/deployments/merge-labels.yaml b/internal/infrastructure/kubernetes/ratelimit/testdata/deployments/merge-labels.yaml
index 0c944d8fd..135ec2691 100644
--- a/internal/infrastructure/kubernetes/ratelimit/testdata/deployments/merge-labels.yaml
+++ b/internal/infrastructure/kubernetes/ratelimit/testdata/deployments/merge-labels.yaml
@@ -90,6 +90,15 @@ spec:
           value: /etc/statsd-exporter/conf.yaml
         image: docker.io/envoyproxy/ratelimit:master
         imagePullPolicy: IfNotPresent
+        livenessProbe:
+          failureThreshold: 3
+          httpGet:
+            path: /healthcheck
+            port: 8080
+            scheme: HTTP
+          periodSeconds: 10
+          successThreshold: 1
+          timeoutSeconds: 1
         name: envoy-ratelimit
         ports:
         - containerPort: 8081
diff --git a/internal/infrastructure/kubernetes/ratelimit/testdata/deployments/override-env.yaml b/internal/infrastructure/kubernetes/ratelimit/testdata/deployments/override-env.yaml
index 0c0f73f3c..3664b57ad 100644
--- a/internal/infrastructure/kubernetes/ratelimit/testdata/deployments/override-env.yaml
+++ b/internal/infrastructure/kubernetes/ratelimit/testdata/deployments/override-env.yaml
@@ -89,6 +89,15 @@ spec:
           value: /etc/statsd-exporter/conf.yaml
         image: custom-image
         imagePullPolicy: IfNotPresent
+        livenessProbe:
+          failureThreshold: 3
+          httpGet:
+            path: /healthcheck
+            port: 8080
+            scheme: HTTP
+          periodSeconds: 10
+          successThreshold: 1
+          timeoutSeconds: 1
         name: envoy-ratelimit
         ports:
         - containerPort: 8081
diff --git a/internal/infrastructure/kubernetes/ratelimit/testdata/deployments/patch-deployment-containers.yaml b/internal/infrastructure/kubernetes/ratelimit/testdata/deployments/patch-deployment-containers.yaml
index 309c2d20d..462437dfc 100644
--- a/internal/infrastructure/kubernetes/ratelimit/testdata/deployments/patch-deployment-containers.yaml
+++ b/internal/infrastructure/kubernetes/ratelimit/testdata/deployments/patch-deployment-containers.yaml
@@ -90,6 +90,15 @@ spec:
           value: /etc/statsd-exporter/conf.yaml
         image: docker.io/envoyproxy/ratelimit:master
         imagePullPolicy: Always
+        livenessProbe:
+          failureThreshold: 3
+          httpGet:
+            path: /healthcheck
+            port: 8080
+            scheme: HTTP
+          periodSeconds: 10
+          successThreshold: 1
+          timeoutSeconds: 1
         name: envoy-ratelimit
         ports:
         - containerPort: 8081
diff --git a/internal/infrastructure/kubernetes/ratelimit/testdata/deployments/patch-deployment.yaml b/internal/infrastructure/kubernetes/ratelimit/testdata/deployments/patch-deployment.yaml
index 5556e12d2..18ff23d25 100644
--- a/internal/infrastructure/kubernetes/ratelimit/testdata/deployments/patch-deployment.yaml
+++ b/internal/infrastructure/kubernetes/ratelimit/testdata/deployments/patch-deployment.yaml
@@ -88,6 +88,15 @@ spec:
           value: /etc/statsd-exporter/conf.yaml
         image: docker.io/envoyproxy/ratelimit:master
         imagePullPolicy: IfNotPresent
+        livenessProbe:
+          failureThreshold: 3
+          httpGet:
+            path: /healthcheck
+            port: 8080
+            scheme: HTTP
+          periodSeconds: 10
+          successThreshold: 1
+          timeoutSeconds: 1
         name: envoy-ratelimit
         ports:
         - containerPort: 8081
diff --git a/internal/infrastructure/kubernetes/ratelimit/testdata/deployments/redis-tls-settings.yaml b/internal/infrastructure/kubernetes/ratelimit/testdata/deployments/redis-tls-settings.yaml
index 29428fc44..a7d0cacf4 100644
--- a/internal/infrastructure/kubernetes/ratelimit/testdata/deployments/redis-tls-settings.yaml
+++ b/internal/infrastructure/kubernetes/ratelimit/testdata/deployments/redis-tls-settings.yaml
@@ -97,6 +97,15 @@ spec:
           value: redis_auth_password
         image: custom-image
         imagePullPolicy: IfNotPresent
+        livenessProbe:
+          failureThreshold: 3
+          httpGet:
+            path: /healthcheck
+            port: 8080
+            scheme: HTTP
+          periodSeconds: 10
+          successThreshold: 1
+          timeoutSeconds: 1
         name: envoy-ratelimit
         ports:
         - containerPort: 8081
diff --git a/internal/infrastructure/kubernetes/ratelimit/testdata/deployments/tolerations.yaml b/internal/infrastructure/kubernetes/ratelimit/testdata/deployments/tolerations.yaml
index a24782226..d76e45090 100644
--- a/internal/infrastructure/kubernetes/ratelimit/testdata/deployments/tolerations.yaml
+++ b/internal/infrastructure/kubernetes/ratelimit/testdata/deployments/tolerations.yaml
@@ -97,6 +97,15 @@ spec:
           value: redis_auth_password
         image: custom-image
         imagePullPolicy: IfNotPresent
+        livenessProbe:
+          failureThreshold: 3
+          httpGet:
+            path: /healthcheck
+            port: 8080
+            scheme: HTTP
+          periodSeconds: 10
+          successThreshold: 1
+          timeoutSeconds: 1
         name: envoy-ratelimit
         ports:
         - containerPort: 8081
diff --git a/internal/infrastructure/kubernetes/ratelimit/testdata/deployments/volumes.yaml b/internal/infrastructure/kubernetes/ratelimit/testdata/deployments/volumes.yaml
index 30d8852d6..b6a834a1c 100644
--- a/internal/infrastructure/kubernetes/ratelimit/testdata/deployments/volumes.yaml
+++ b/internal/infrastructure/kubernetes/ratelimit/testdata/deployments/volumes.yaml
@@ -97,6 +97,15 @@ spec:
           value: redis_auth_password
         image: custom-image
         imagePullPolicy: IfNotPresent
+        livenessProbe:
+          failureThreshold: 3
+          httpGet:
+            path: /healthcheck
+            port: 8080
+            scheme: HTTP
+          periodSeconds: 10
+          successThreshold: 1
+          timeoutSeconds: 1
         name: envoy-ratelimit
         ports:
         - containerPort: 8081
diff --git a/internal/infrastructure/kubernetes/ratelimit/testdata/deployments/with-node-selector.yaml b/internal/infrastructure/kubernetes/ratelimit/testdata/deployments/with-node-selector.yaml
index f65e6f23e..9e08bb7ad 100644
--- a/internal/infrastructure/kubernetes/ratelimit/testdata/deployments/with-node-selector.yaml
+++ b/internal/infrastructure/kubernetes/ratelimit/testdata/deployments/with-node-selector.yaml
@@ -88,6 +88,15 @@ spec:
           value: /etc/statsd-exporter/conf.yaml
         image: docker.io/envoyproxy/ratelimit:master
         imagePullPolicy: IfNotPresent
+        livenessProbe:
+          failureThreshold: 3
+          httpGet:
+            path: /healthcheck
+            port: 8080
+            scheme: HTTP
+          periodSeconds: 10
+          successThreshold: 1
+          timeoutSeconds: 1
         name: envoy-ratelimit
         ports:
         - containerPort: 8081
diff --git a/internal/infrastructure/kubernetes/ratelimit/testdata/deployments/with-topology-spread-constraints.yaml b/internal/infrastructure/kubernetes/ratelimit/testdata/deployments/with-topology-spread-constraints.yaml
index e726269cc..13357946e 100644
--- a/internal/infrastructure/kubernetes/ratelimit/testdata/deployments/with-topology-spread-constraints.yaml
+++ b/internal/infrastructure/kubernetes/ratelimit/testdata/deployments/with-topology-spread-constraints.yaml
@@ -88,6 +88,15 @@ spec:
           value: /etc/statsd-exporter/conf.yaml
         image: docker.io/envoyproxy/ratelimit:master
         imagePullPolicy: IfNotPresent
+        livenessProbe:
+          failureThreshold: 3
+          httpGet:
+            path: /healthcheck
+            port: 8080
+            scheme: HTTP
+          periodSeconds: 10
+          successThreshold: 1
+          timeoutSeconds: 1
         name: envoy-ratelimit
         ports:
         - containerPort: 8081
diff --git a/internal/ir/xds_test.go b/internal/ir/xds_test.go
index cfbd84c91..c1af9ce19 100644
--- a/internal/ir/xds_test.go
+++ b/internal/ir/xds_test.go
@@ -1172,6 +1172,53 @@ func TestValidateRouteDestination(t *testing.T) {
 			},
 			want: ErrDestinationNameEmpty,
 		},
+		{
+			name: "mixed address types with MIXED in destinations",
+			input: RouteDestination{
+				Settings: []*DestinationSetting{
+					{
+						Endpoints: []*DestinationEndpoint{
+							{
+								Host: "10.11.12.13",
+								Port: 8080,
+							},
+							{
+								Host: "example.com",
+								Port: 8080,
+							},
+						},
+						AddressType: ptr.To(MIXED),
+					},
+				},
+			},
+			want: ErrRouteDestinationsFQDNMixed,
+		},
+		{
+			name: "mixed address types with FQDN in destinations",
+			input: RouteDestination{
+				Settings: []*DestinationSetting{
+					{
+						Endpoints: []*DestinationEndpoint{
+							{
+								Host: "10.11.12.13",
+								Port: 8080,
+							},
+						},
+						AddressType: ptr.To(IP),
+					},
+					{
+						Endpoints: []*DestinationEndpoint{
+							{
+								Host: "example.com",
+								Port: 8080,
+							},
+						},
+						AddressType: ptr.To(FQDN),
+					},
+				},
+			},
+			want: ErrRouteDestinationsFQDNMixed,
+		},
 	}
 	for _, test := range tests {
 		t.Run(test.name, func(t *testing.T) {
diff --git a/site/content/en/latest/install/install-helm.md b/site/content/en/latest/install/install-helm.md
index 2fbb01532..d146194d3 100644
--- a/site/content/en/latest/install/install-helm.md
+++ b/site/content/en/latest/install/install-helm.md
@@ -63,7 +63,7 @@ consideration when debugging.
 
 [Helm](https://helm.sh/docs/chart_best_practices/custom_resource_definitions/#some-caveats-and-explanations) does not update CRDs
 that live in the `/crds` folder in the Helm Chart. So you will manually need to update the CRDs.
-Follow the steps outlined in [this](./install-yaml/#upgrading-from-v1.1) section if you're upgrading from a previous version.
+Follow the steps outlined in [this](./install-yaml/#upgrading-from-v1.2) section if you're upgrading from a previous version.
 
 ## Helm chart customizations
 
diff --git a/site/content/en/latest/install/install-yaml.md b/site/content/en/latest/install/install-yaml.md
index 0da5ca9cc..eac18063e 100644
--- a/site/content/en/latest/install/install-yaml.md
+++ b/site/content/en/latest/install/install-yaml.md
@@ -38,14 +38,11 @@ Refer to the [Developer Guide](../../contributions/develop) to learn more.
 
    Envoy Gateway should now be successfully installed and running, but in order to experience more abilities of Envoy Gateway, you can refer to [Tasks](/latest/tasks).
 
-## Upgrading from v1.1
+## Upgrading from v1.2
 
-Some manual migration steps are required to upgrade Envoy Gateway to v1.2.
+Some manual migration steps are required to upgrade Envoy Gateway to v1.3.
 
-1. Update your `GRPCRoute` and `ReferenceGrant` resources if the storage version being used is `v1alpha2`.
-Follow the steps in Gateway-API [v1.2 Upgrade Notes](https://gateway-api.sigs.k8s.io/guides/#v12-upgrade-notes)
-
-2. Update Gateway-API and Envoy Gateway CRDs:
+1. Update Gateway-API and Envoy Gateway CRDs:
 
 ```shell
 helm pull oci://docker.io/envoyproxy/gateway-helm --version {{< yaml-version >}} --untar
@@ -53,7 +50,7 @@ kubectl apply --force-conflicts --server-side -f ./gateway-helm/crds/gatewayapi-
 kubectl apply --force-conflicts --server-side -f ./gateway-helm/crds/generated
 ```
 
-3. Install Envoy Gateway {{< yaml-version >}}:
+2. Install Envoy Gateway {{< yaml-version >}}:
 
 ```shell
 helm upgrade eg oci://docker.io/envoyproxy/gateway-helm --version {{< yaml-version >}} -n envoy-gateway-system