=== T10: VirtualService route ordering (first-match-wins vs specificity) === Namespace: istio-vt-t10 NOTE: manifests field was a single combined YAML (client-echo.yaml + order-vs-catchall-first.yaml collapsed by the harness). All 4 objects were applied together as manifest.yaml in one shot (see step 2 of task). The spec 'commands' below are run in order; the first two apply steps are adapted to point at manifest.yaml (idempotent kubectl apply, no-op on repeat) since separate client-echo.yaml / order-vs-catchall-first.yaml files were never split out. $ kubectl apply -f manifest.yaml (adapted from: kubectl apply -f client-echo.yaml) && kubectl -n istio-vt-t10 wait --for=condition=Ready pod/client --timeout=90s pod/client configured deployment.apps/echo unchanged service/echo unchanged virtualservice.networking.istio.io/order-vs-catchall-first unchanged pod/client condition met $ kubectl apply -f manifest.yaml (adapted from: kubectl apply -f order-vs-catchall-first.yaml) pod/client configured deployment.apps/echo unchanged service/echo unchanged virtualservice.networking.istio.io/order-vs-catchall-first unchanged $ sleep 5 (slept 5s) $ kubectl -n istio-vt-t10 exec client -c curl -- curl -s -o /dev/null -w 'root=%{http_code} ' http://echo.istio-vt-t10.svc.homelab.local/ root=200 $ kubectl -n istio-vt-t10 exec client -c curl -- curl -s -o /dev/null -w 'status_path=%{http_code} ' http://echo.istio-vt-t10.svc.homelab.local/status/whatever status_path=200 === supplementary: repeat both requests 3x each to rule out flakiness === root_retry1=200 root_retry2=200 root_retry3=200 status_retry1=200 status_retry2=200 status_retry3=200 === VirtualService as stored (order preserved) === apiVersion: networking.istio.io/v1 kind: VirtualService metadata: annotations: kubectl.kubernetes.io/last-applied-configuration: | {"apiVersion":"networking.istio.io/v1","kind":"VirtualService","metadata":{"annotations":{},"name":"order-vs-catchall-first","namespace":"istio-vt-t10"},"spec":{"hosts":["echo.istio-vt-t10.svc.homelab.local"],"http":[{"fault":{"abort":{"httpStatus":200,"percentage":{"value":100}}},"match":[{"uri":{"prefix":"/"}}],"route":[{"destination":{"host":"echo.istio-vt-t10.svc.homelab.local"}}]},{"fault":{"abort":{"httpStatus":418,"percentage":{"value":100}}},"match":[{"uri":{"prefix":"/status"}}],"route":[{"destination":{"host":"echo.istio-vt-t10.svc.homelab.local"}}]}]}} creationTimestamp: "2026-07-04T22:46:40Z" generation: 1 name: order-vs-catchall-first namespace: istio-vt-t10 resourceVersion: "13643085" uid: 1f35ff3d-7076-4263-a8ec-cb585ee11eb7 spec: hosts: - echo.istio-vt-t10.svc.homelab.local http: - fault: abort: httpStatus: 200 percentage: value: 100 match: - uri: prefix: / route: - destination: host: echo.istio-vt-t10.svc.homelab.local - fault: abort: httpStatus: 418 percentage: value: 100 match: - uri: prefix: /status route: - destination: host: echo.istio-vt-t10.svc.homelab.local === istioctl analyze (checks for known route-shadowing warnings) === Error [IST0101] (VirtualService istio-vt-t10/order-vs-catchall-first) Referenced host not found: "echo.istio-vt-t10.svc.homelab.local" Info [IST0131] (VirtualService istio-vt-t10/order-vs-catchall-first) VirtualService rule #1 match #0 of prefix /status is not used (duplicate/overlapping match in rule #0 of prefix / on #0). Info [IST0135] (Pod istio-vt-t10/client) Annotation "sidecar.istio.io/inject" has been deprecated in favor of the "sidecar.istio.io/inject" label and may not work in future Istio versions. Info [IST0135] (Pod istio-vt-t10/echo-5767bbcc56-5rh68) Annotation "sidecar.istio.io/inject" has been deprecated in favor of the "sidecar.istio.io/inject" label and may not work in future Istio versions. Error: Analyzers found issues when analyzing namespace: istio-vt-t10. See https://istio.io/v1.30/docs/reference/config/analysis for more information about causes and resolutions. === proxy-config routes for echo cluster on client sidecar (to see envoy route table order) === Error: failed retrieving: deployments.apps "client" not found in the "istio-vt-t10" namespace === proxy-config routes for echo host on client sidecar (corrected: pod/client) === [] === decisive evidence: compiled Envoy route table for echo.istio-vt-t10.svc.homelab.local:80 === (via: istioctl proxy-config routes pod/client -n istio-vt-t10 --name 80 -o json, filtered to homelab.local vhost) { "name": "echo.istio-vt-t10.svc.homelab.local:80", "domains": [ "echo.istio-vt-t10.svc.homelab.local" ], "routes": [ { "match": { "prefix": "/", "caseSensitive": true }, "route": { "cluster": "outbound|80||echo.istio-vt-t10.svc.homelab.local", "timeout": "0s", "retryPolicy": { "retryOn": "connect-failure,refused-stream,unavailable,cancelled,retriable-status-codes", "numRetries": 2, "retryHostPredicate": [ { "name": "envoy.retry_host_predicates.previous_hosts", "typedConfig": { "@type": "type.googleapis.com/envoy.extensions.retry.host.previous_hosts.v3.PreviousHostsPredicate" } } ], "hostSelectionRetryMaxAttempts": "5" }, "maxGrpcTimeout": "0s" }, "metadata": { "filterMetadata": { "istio": { "config": "/apis/networking.istio.io/v1/namespaces/istio-vt-t10/virtual-service/order-vs-catchall-first" } } }, "decorator": { "operation": "echo.istio-vt-t10.svc.homelab.local:80/*" }, "typedPerFilterConfig": { "envoy.filters.http.fault": { "@type": "type.googleapis.com/envoy.extensions.filters.http.fault.v3.HTTPFault", "abort": { "httpStatus": 200, "percentage": { "numerator": 1000000, "denominator": "MILLION" } } } } } ], "includeRequestAttemptCount": true } OBSERVATION: only ONE compiled route entry exists (prefix '/', abort httpStatus 200). The second VirtualService rule (prefix '/status', abort httpStatus 418) was never compiled into the Envoy route table at all -- it was dropped/shadowed by the earlier catch-all rule at xDS-translation time, consistent with the IST0131 analyzer warning above.