Repository: envoyproxy/gateway
Pull request #5176 (2025-01-30 20:21:16)

fail validation if baseInterval is 0s
Fixes: https://github.com/envoyproxy/gateway/issues/5147

codecov[bot]: ## [Codecov](https://app.codecov.io/gh/envoyproxy/gateway/pull/5176?dropdown=coverage&src=pr&el=h1&utm_medium=referral&utm_source=github&utm_content=comment&utm_campaign=pr+comments&utm_term=envoyproxy) Report
Attention: Patch coverage is `62.50000%` with `6 lines` in your changes missing coverage. Please review.
> Project coverage is 66.81%. Comparing base [(`e904d3f`)](https://app.codecov.io/gh/envoyproxy/gateway/commit/e904d3fe40c2b794fbb0f494239ac76c6db9a56c?dropdown=coverage&el=desc&utm_medium=referral&utm_source=github&utm_content=comment&utm_campaign=pr+comments&utm_term=envoyproxy) to head [(`98f4ce7`)](https://app.codecov.io/gh/envoyproxy/gateway/commit/98f4ce7e76d1e093634a21d1826b5b76ea961728?dropdown=coverage&el=desc&utm_medium=referral&utm_source=github&utm_content=comment&utm_campaign=pr+comments&utm_term=envoyproxy).
> Report is 2 commits behind head on main.

| [Files with missing lines](https://app.codecov.io/gh/envoyproxy/gateway/pull/5176?dropdown=coverage&src=pr&el=tree&utm_medium=referral&utm_source=github&utm_content=comment&utm_campaign=pr+comments&utm_term=envoyproxy) | Patch % | Lines |
|---|---|---|
| [internal/gatewayapi/backendtrafficpolicy.go](https://app.codecov.io/gh/envoyproxy/gateway/pull/5176?src=pr&el=tree&filepath=internal%2Fgatewayapi%2Fbackendtrafficpolicy.go&utm_medium=referral&utm_source=github&utm_content=comment&utm_campaign=pr+comments&utm_term=envoyproxy#diff-aW50ZXJuYWwvZ2F0ZXdheWFwaS9iYWNrZW5kdHJhZmZpY3BvbGljeS5nbw==) | 50.00% | [2 Missing and 1 partial :warning: ](https://app.codecov.io/gh/envoyproxy/gateway/pull/5176?src=pr&el=tree&utm_medium=referral&utm_source=github&utm_content=comment&utm_campaign=pr+comments&utm_term=envoyproxy) |
| [internal/gatewayapi/clustersettings.go](https://app.codecov.io/gh/envoyproxy/gateway/pull/5176?src=pr&el=tree&filepath=internal%2Fgatewayapi%2Fclustersettings.go&utm_medium=referral&utm_source=github&utm_content=comment&utm_campaign=pr+comments&utm_term=envoyproxy#diff-aW50ZXJuYWwvZ2F0ZXdheWFwaS9jbHVzdGVyc2V0dGluZ3MuZ28=) | 70.00% | [2 Missing and 1 partial :warning: ](https://app.codecov.io/gh/envoyproxy/gateway/pull/5176?src=pr&el=tree&utm_medium=referral&utm_source=github&utm_content=comment&utm_campaign=pr+comments&utm_term=envoyproxy) |

<details><summary>Additional details and impacted files</summary>


```diff
@@            Coverage Diff             @@
##             main    #5176      +/-   ##
==========================================
- Coverage   66.89%   66.81%   -0.09%     
==========================================
  Files         210      210              
  Lines       32979    32983       +4     
==========================================
- Hits        22061    22037      -24     
- Misses       9581     9602      +21     
- Partials     1337     1344       +7     
```

</details>

[:umbrella: View full report in Codecov by Sentry](https://app.codecov.io/gh/envoyproxy/gateway/pull/5176?dropdown=coverage&src=pr&el=continue&utm_medium=referral&utm_source=github&utm_content=comment&utm_campaign=pr+comments&utm_term=envoyproxy).   
:loudspeaker: Have feedback on the report? [Share it here](https://about.codecov.io/codecov-pr-comment-feedback/?utm_medium=referral&utm_source=github&utm_content=comment&utm_campaign=pr+comments&utm_term=envoyproxy).


Patch:
diff --git a/internal/gatewayapi/backendtrafficpolicy.go b/internal/gatewayapi/backendtrafficpolicy.go
index 3bdc92d47..16d00920c 100644
--- a/internal/gatewayapi/backendtrafficpolicy.go
+++ b/internal/gatewayapi/backendtrafficpolicy.go
@@ -333,9 +333,12 @@ func (t *Translator) translateBackendTrafficPolicyForRoute(
 		err = perr.WithMessage(err, "TCPKeepalive")
 		errs = errors.Join(errs, err)
 	}
-	if policy.Spec.Retry != nil {
-		rt = buildRetry(policy.Spec.Retry)
+
+	if rt, err = buildRetry(policy.Spec.Retry); err != nil {
+		err = perr.WithMessage(err, "Retry")
+		errs = errors.Join(errs, err)
 	}
+
 	if to, err = buildClusterSettingsTimeout(policy.Spec.ClusterSettings); err != nil {
 		err = perr.WithMessage(err, "Timeout")
 		errs = errors.Join(errs, err)
@@ -484,9 +487,12 @@ func (t *Translator) translateBackendTrafficPolicyForGateway(
 		err = perr.WithMessage(err, "TCPKeepalive")
 		errs = errors.Join(errs, err)
 	}
-	if policy.Spec.Retry != nil {
-		rt = buildRetry(policy.Spec.Retry)
+
+	if rt, err = buildRetry(policy.Spec.Retry); err != nil {
+		err = perr.WithMessage(err, "Retry")
+		errs = errors.Join(errs, err)
 	}
+
 	if ct, err = buildClusterSettingsTimeout(policy.Spec.ClusterSettings); err != nil {
 		err = perr.WithMessage(err, "Timeout")
 		errs = errors.Join(errs, err)
diff --git a/internal/gatewayapi/clustersettings.go b/internal/gatewayapi/clustersettings.go
index 5706504f4..76d3e1aea 100644
--- a/internal/gatewayapi/clustersettings.go
+++ b/internal/gatewayapi/clustersettings.go
@@ -72,7 +72,10 @@ func translateTrafficFeatures(policy *egv1a1.ClusterSettings) (*ir.TrafficFeatur
 		ret.HTTP2 = h2
 	}
 
-	ret.Retry = buildRetry(policy.Retry)
+	var err error
+	if ret.Retry, err = buildRetry(policy.Retry); err != nil {
+		return nil, err
+	}
 
 	// If nothing was set in any of the above calls, return nil instead of an empty
 	// container
@@ -477,9 +480,9 @@ func translateDNS(policy egv1a1.ClusterSettings) *ir.DNS {
 	}
 }
 
-func buildRetry(r *egv1a1.Retry) *ir.Retry {
+func buildRetry(r *egv1a1.Retry) (*ir.Retry, error) {
 	if r == nil {
-		return nil
+		return nil, nil
 	}
 
 	rt := &ir.Retry{}
@@ -518,13 +521,22 @@ func buildRetry(r *egv1a1.Retry) *ir.Retry {
 		if r.PerRetry.BackOff != nil {
 			if r.PerRetry.BackOff.MaxInterval != nil || r.PerRetry.BackOff.BaseInterval != nil {
 				bop := &ir.BackOffPolicy{}
+				if r.PerRetry.BackOff.BaseInterval != nil {
+					bop.BaseInterval = r.PerRetry.BackOff.BaseInterval
+					if bop.BaseInterval.Duration == 0 {
+						return nil, fmt.Errorf("baseInterval cannot be set to 0s")
+					}
+				}
 				if r.PerRetry.BackOff.MaxInterval != nil {
 					bop.MaxInterval = r.PerRetry.BackOff.MaxInterval
+					if bop.MaxInterval.Duration == 0 {
+						return nil, fmt.Errorf("maxInterval cannot be set to 0s")
+					}
+					if bop.BaseInterval != nil && bop.BaseInterval.Duration > bop.MaxInterval.Duration {
+						return nil, fmt.Errorf("maxInterval cannot be less than baseInterval")
+					}
 				}
 
-				if r.PerRetry.BackOff.BaseInterval != nil {
-					bop.BaseInterval = r.PerRetry.BackOff.BaseInterval
-				}
 				pr.BackOff = bop
 				bpr = true
 			}
@@ -535,5 +547,5 @@ func buildRetry(r *egv1a1.Retry) *ir.Retry {
 		}
 	}
 
-	return rt
+	return rt, nil
 }
diff --git a/release-notes/v1.3.0-rc.1.yaml b/release-notes/v1.3.0-rc.1.yaml
index dd40242ca..39f9b8e8f 100644
--- a/release-notes/v1.3.0-rc.1.yaml
+++ b/release-notes/v1.3.0-rc.1.yaml
@@ -3,13 +3,10 @@ date: January 23, 2025
 # Changes that are expected to cause an incompatibility with previous versions, such as deletions or modifications to existing APIs.
 breaking changes: |
   The Container `ports` field of the gateway instance has been removed, which will cause the gateway Pod to be rebuilt when upgrading the version.
-  ClientTrafficPolicy previously treated an empty TLS ALPNProtocols list as being undefined and applied Envoy Gateway defaults.
-  An empty TLS ALPNProtocols list is now treated as user-defined disablement of the TLS ALPN extension.
-  Outlier detection (passive health check) is now disabled by default.
-  refer to https://gateway.envoyproxy.io/docs/api/extension_types/#backendtrafficpolicy for working with passive health checks.
+  ClientTrafficPolicy previously treated an empty TLS ALPNProtocols list as being undefined and applied Envoy Gateway defaults. An empty TLS ALPNProtocols list is now treated as user-defined disablement of the TLS ALPN extension.
+  Outlier detection (passive health check) is now disabled by default. refer to https://gateway.envoyproxy.io/docs/api/extension_types/#backendtrafficpolicy for working with passive health checks.
   Envoy Gateway treats errors in calls to an extension service as fail-closed by default. Any error returned from the extension server will replace the affected resource with an "Internal Server Error" immediate response. The previous behavior can be enabled by setting the `failOpen` field to `true` in the extension service configuration.
-  Envoy Gateway now return a 500 response when a ClientTrafficPolicy translation fails for HTTP/GRPC routes, and forwards.
-  client traffic to an empty cluster when a ClientTrafficPolicy translation fails for TCP routes.
+  Envoy Gateway now return a 500 response when a ClientTrafficPolicy translation fails for HTTP/GRPC routes, and forwards client traffic to an empty cluster when a ClientTrafficPolicy translation fails for TCP routes.
   Any issues with `EnvoyProxy` reference in a `Gateway` will prevent the Envoy fleet from being created or result in the deletion of an existing Envoy fleet.
   Envoy Gateway now returns a 500 response when a BackendTLSPolicy translation fails for HTTP/GRPC/TLS routes.
 
@@ -37,10 +34,10 @@ new features: |
   Added support for overriding status code in response overrides ClientTrafficPolicy.
   Added support for AllowModeOverride for ext-proc in EnvoyExtensionPolicy.
   Added support for configuring remote JWKS settings with BackendCluster in SecurityPolicy.
-  Added support for infra deployment in the gateway namespace.
   Added support for sending body to Ext-Auth server in SecurityPolicy.
   Added support for Sending attributes to ext-proc in EnvoyExtensionPolicy.
   Added support for configuring hostEnvKeys for Wasm extensions in EnvoyExtensionPolicy.
+  Gateway API Route rule name is propagated to XDS metadata as sectionName.
 
 bug fixes: |
   Fixed a panic in the provider goroutine when the body in the direct response configuration was nil.
@@ -68,7 +65,6 @@ bug fixes: |
   Fixed limitations that prevented creation of FQDN Endpoints with a single-character subdomain in Backend.
   Fixed issue where SecurityContext of shutdown-manager container was not updated by overriding helm values.
   Fixed issue with incorrect IPFamily detection for backends.
-  Gateway API Route rule name is propagated to XDS metadata as sectionName.
 
 # Other notable changes not covered by the above sections.
 Other changes: |
diff --git a/site/content/en/news/releases/notes/v1.3.0-rc.1.md b/site/content/en/news/releases/notes/v1.3.0-rc.1.md
index dfbe3e22c..673b740f7 100644
--- a/site/content/en/news/releases/notes/v1.3.0-rc.1.md
+++ b/site/content/en/news/releases/notes/v1.3.0-rc.1.md
@@ -7,13 +7,10 @@ Date: January 23, 2025
 
 ## Breaking changes
 - The Container `ports` field of the gateway instance has been removed, which will cause the gateway Pod to be rebuilt when upgrading the version.
-- ClientTrafficPolicy previously treated an empty TLS ALPNProtocols list as being undefined and applied Envoy Gateway defaults.
-- An empty TLS ALPNProtocols list is now treated as user-defined disablement of the TLS ALPN extension.
-- Outlier detection (passive health check) is now disabled by default.
-- refer to https://gateway.envoyproxy.io/docs/api/extension_types/#backendtrafficpolicy for working with passive health checks.
+- ClientTrafficPolicy previously treated an empty TLS ALPNProtocols list as being undefined and applied Envoy Gateway defaults. An empty TLS ALPNProtocols list is now treated as user-defined disablement of the TLS ALPN extension.
+- Outlier detection (passive health check) is now disabled by default. refer to https://gateway.envoyproxy.io/docs/api/extension_types/#backendtrafficpolicy for working with passive health checks.
 - Envoy Gateway treats errors in calls to an extension service as fail-closed by default. Any error returned from the extension server will replace the affected resource with an "Internal Server Error" immediate response. The previous behavior can be enabled by setting the `failOpen` field to `true` in the extension service configuration.
-- Envoy Gateway now return a 500 response when a ClientTrafficPolicy translation fails for HTTP/GRPC routes, and forwards.
-- client traffic to an empty cluster when a ClientTrafficPolicy translation fails for TCP routes.
+- Envoy Gateway now return a 500 response when a ClientTrafficPolicy translation fails for HTTP/GRPC routes, and forwards client traffic to an empty cluster when a ClientTrafficPolicy translation fails for TCP routes.
 - Any issues with `EnvoyProxy` reference in a `Gateway` will prevent the Envoy fleet from being created or result in the deletion of an existing Envoy fleet.
 - Envoy Gateway now returns a 500 response when a BackendTLSPolicy translation fails for HTTP/GRPC/TLS routes.
 
@@ -39,10 +36,10 @@ Date: January 23, 2025
 - Added support for overriding status code in response overrides ClientTrafficPolicy.
 - Added support for AllowModeOverride for ext-proc in EnvoyExtensionPolicy.
 - Added support for configuring remote JWKS settings with BackendCluster in SecurityPolicy.
-- Added support for infra deployment in the gateway namespace.
 - Added support for sending body to Ext-Auth server in SecurityPolicy.
 - Added support for Sending attributes to ext-proc in EnvoyExtensionPolicy.
 - Added support for configuring hostEnvKeys for Wasm extensions in EnvoyExtensionPolicy.
+- Gateway API Route rule name is propagated to XDS metadata as sectionName.
 
 ## Bug fixes
 - Fixed a panic in the provider goroutine when the body in the direct response configuration was nil.
@@ -70,7 +67,6 @@ Date: January 23, 2025
 - Fixed limitations that prevented creation of FQDN Endpoints with a single-character subdomain in Backend.
 - Fixed issue where SecurityContext of shutdown-manager container was not updated by overriding helm values.
 - Fixed issue with incorrect IPFamily detection for backends.
-- Gateway API Route rule name is propagated to XDS metadata as sectionName.
 
 ## Other changes
 - Bumped Gateway API to v1.2.1.


Test patch:
diff --git a/internal/gatewayapi/testdata/backendtrafficpolicy-with-retries.in.yaml b/internal/gatewayapi/testdata/backendtrafficpolicy-with-retries.in.yaml
index be4649ab4..bf2e264bf 100644
--- a/internal/gatewayapi/testdata/backendtrafficpolicy-with-retries.in.yaml
+++ b/internal/gatewayapi/testdata/backendtrafficpolicy-with-retries.in.yaml
@@ -62,6 +62,44 @@ httpRoutes:
       backendRefs:
       - name: service-1
         port: 8080
+- 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-2
+      sectionName: http
+    rules:
+    - matches:
+      - path:
+          value: "/route2"
+      backendRefs:
+      - name: service-1
+        port: 8080
+- 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-2
+      sectionName: http
+    rules:
+    - matches:
+      - path:
+          value: "/route3"
+      backendRefs:
+      - name: service-1
+        port: 8080
 backendTrafficPolicies:
 - apiVersion: gateway.envoyproxy.io/v1alpha1
   kind: BackendTrafficPolicy
@@ -86,7 +124,7 @@ backendTrafficPolicies:
   kind: BackendTrafficPolicy
   metadata:
     namespace: default
-    name: policy-for-route
+    name: policy-for-route-1
   spec:
     targetRef:
       group: gateway.networking.k8s.io
@@ -106,3 +144,32 @@ backendTrafficPolicies:
         backoff:
           baseInterval: 100ms
           maxInterval: 10s
+- apiVersion: gateway.envoyproxy.io/v1alpha1
+  kind: BackendTrafficPolicy
+  metadata:
+    namespace: default
+    name: policy-for-route-2
+  spec:
+    targetRef:
+      group: gateway.networking.k8s.io
+      kind: HTTPRoute
+      name: httproute-2
+    retry:
+      perRetry:
+        backoff:
+          baseInterval: 0s
+- apiVersion: gateway.envoyproxy.io/v1alpha1
+  kind: BackendTrafficPolicy
+  metadata:
+    namespace: default
+    name: policy-for-route-3
+  spec:
+    targetRef:
+      group: gateway.networking.k8s.io
+      kind: HTTPRoute
+      name: httproute-3
+    retry:
+      perRetry:
+        backoff:
+          baseInterval: 2s
+          maxInterval: 1s
diff --git a/internal/gatewayapi/testdata/backendtrafficpolicy-with-retries.out.yaml b/internal/gatewayapi/testdata/backendtrafficpolicy-with-retries.out.yaml
index 40ae88b60..2e3dd5bbb 100644
--- a/internal/gatewayapi/testdata/backendtrafficpolicy-with-retries.out.yaml
+++ b/internal/gatewayapi/testdata/backendtrafficpolicy-with-retries.out.yaml
@@ -3,7 +3,7 @@ backendTrafficPolicies:
   kind: BackendTrafficPolicy
   metadata:
     creationTimestamp: null
-    name: policy-for-route
+    name: policy-for-route-1
     namespace: default
   spec:
     retry:
@@ -39,6 +39,67 @@ backendTrafficPolicies:
         status: "True"
         type: Accepted
       controllerName: gateway.envoyproxy.io/gatewayclass-controller
+- apiVersion: gateway.envoyproxy.io/v1alpha1
+  kind: BackendTrafficPolicy
+  metadata:
+    creationTimestamp: null
+    name: policy-for-route-2
+    namespace: default
+  spec:
+    retry:
+      perRetry:
+        backOff:
+          baseInterval: 0s
+    targetRef:
+      group: gateway.networking.k8s.io
+      kind: HTTPRoute
+      name: httproute-2
+  status:
+    ancestors:
+    - ancestorRef:
+        group: gateway.networking.k8s.io
+        kind: Gateway
+        name: gateway-2
+        namespace: envoy-gateway
+        sectionName: http
+      conditions:
+      - lastTransitionTime: null
+        message: 'Retry: baseInterval cannot be set to 0s.'
+        reason: Invalid
+        status: "False"
+        type: Accepted
+      controllerName: gateway.envoyproxy.io/gatewayclass-controller
+- apiVersion: gateway.envoyproxy.io/v1alpha1
+  kind: BackendTrafficPolicy
+  metadata:
+    creationTimestamp: null
+    name: policy-for-route-3
+    namespace: default
+  spec:
+    retry:
+      perRetry:
+        backOff:
+          baseInterval: 2s
+          maxInterval: 1s
+    targetRef:
+      group: gateway.networking.k8s.io
+      kind: HTTPRoute
+      name: httproute-3
+  status:
+    ancestors:
+    - ancestorRef:
+        group: gateway.networking.k8s.io
+        kind: Gateway
+        name: gateway-2
+        namespace: envoy-gateway
+        sectionName: http
+      conditions:
+      - lastTransitionTime: null
+        message: 'Retry: maxInterval cannot be less than baseInterval.'
+        reason: Invalid
+        status: "False"
+        type: Accepted
+      controllerName: gateway.envoyproxy.io/gatewayclass-controller
 - apiVersion: gateway.envoyproxy.io/v1alpha1
   kind: BackendTrafficPolicy
   metadata:
@@ -131,7 +192,7 @@ gateways:
       protocol: HTTP
   status:
     listeners:
-    - attachedRoutes: 1
+    - attachedRoutes: 3
       conditions:
       - lastTransitionTime: null
         message: Sending translated listener configuration to the data plane
@@ -227,6 +288,82 @@ httpRoutes:
         name: gateway-2
         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-2
+      namespace: envoy-gateway
+      sectionName: http
+    rules:
+    - backendRefs:
+      - name: service-1
+        port: 8080
+      matches:
+      - path:
+          value: /route2
+  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-2
+        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-2
+      namespace: envoy-gateway
+      sectionName: http
+    rules:
+    - backendRefs:
+      - name: service-1
+        port: 8080
+      matches:
+      - path:
+          value: /route3
+  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-2
+        namespace: envoy-gateway
+        sectionName: http
 infraIR:
   envoy-gateway/gateway-1:
     proxy:
@@ -325,6 +462,50 @@ xdsIR:
         mergeSlashes: true
       port: 10080
       routes:
+      - destination:
+          name: httproute/default/httproute-2/rule/0
+          settings:
+          - addressType: IP
+            endpoints:
+            - host: 7.7.7.7
+              port: 8080
+            protocol: HTTP
+            weight: 1
+        directResponse:
+          statusCode: 500
+        hostname: gateway.envoyproxy.io
+        isHTTP2: false
+        metadata:
+          kind: HTTPRoute
+          name: httproute-2
+          namespace: default
+        name: httproute/default/httproute-2/rule/0/match/0/gateway_envoyproxy_io
+        pathMatch:
+          distinct: false
+          name: ""
+          prefix: /route2
+      - destination:
+          name: httproute/default/httproute-3/rule/0
+          settings:
+          - addressType: IP
+            endpoints:
+            - host: 7.7.7.7
+              port: 8080
+            protocol: HTTP
+            weight: 1
+        directResponse:
+          statusCode: 500
+        hostname: gateway.envoyproxy.io
+        isHTTP2: false
+        metadata:
+          kind: HTTPRoute
+          name: httproute-3
+          namespace: default
+        name: httproute/default/httproute-3/rule/0/match/0/gateway_envoyproxy_io
+        pathMatch:
+          distinct: false
+          name: ""
+          prefix: /route3
       - destination:
           name: httproute/default/httproute-1/rule/0
           settings: