=== kubectl apply -f manifest.yaml === pod/client created deployment.apps/single-target created service/single-target created destinationrule.networking.istio.io/single-target-outlier created === wait pod/client Ready === pod/client condition met === wait deploy/single-target available === deployment.apps/single-target condition met === pods status === NAME READY STATUS RESTARTS AGE IP NODE NOMINATED NODE READINESS GATES client 2/2 Running 0 5s 10.255.194.109 k8s-worker1 single-target-6fd9ff55b8-hxzvw 2/2 Running 0 5s 10.255.126.10 k8s-worker2 === sanity: confirm outlierDetection attached on client sidecar (via DR host = svc.cluster.local) === "outlierDetection": { "consecutive5xx": 1, "interval": "2s", "baseEjectionTime": "20s", "maxEjectionPercent": 100, "enforcingConsecutive5xx": 100, "enforcingSuccessRate": 0 }, "commonLbConfig": { -- "outlierDetection": { "consecutive5xx": 1, "interval": "2s", "baseEjectionTime": "20s", "maxEjectionPercent": 100, "enforcingConsecutive5xx": 100, "enforcingSuccessRate": 0 }, "commonLbConfig": { === baseline check: normal request returns 200 before any fault === baseline=200 === CMD1 (adapted): trigger REAL upstream 5xx via echo header (not VS fault.abort -- fault.abort is a local reply, proven in T05 to never reach outlier detection) === trigger=503 === CMD4 (adapted FQDN, immediately after trigger): confirm FAILED_OUTLIER_CHECK on cluster.local-named cluster === outbound|443||single-target.istio-vt-t14-r2.svc.cluster.local::outlier::success_rate_average::-1 outbound|443||single-target.istio-vt-t14-r2.svc.cluster.local::outlier::success_rate_ejection_threshold::-1 outbound|443||single-target.istio-vt-t14-r2.svc.cluster.local::outlier::local_origin_success_rate_average::-1 outbound|443||single-target.istio-vt-t14-r2.svc.cluster.local::outlier::local_origin_success_rate_ejection_threshold::-1 outbound|443||single-target.istio-vt-t14-r2.svc.cluster.local::10.255.126.10:8443::health_flags::healthy outbound|80||single-target.istio-vt-t14-r2.svc.cluster.local::outlier::success_rate_average::-1 outbound|80||single-target.istio-vt-t14-r2.svc.cluster.local::outlier::success_rate_ejection_threshold::-1 outbound|80||single-target.istio-vt-t14-r2.svc.cluster.local::outlier::local_origin_success_rate_average::-1 outbound|80||single-target.istio-vt-t14-r2.svc.cluster.local::outlier::local_origin_success_rate_ejection_threshold::-1 outbound|80||single-target.istio-vt-t14-r2.svc.cluster.local::10.255.126.10:8080::health_flags::/failed_outlier_check === rq_error / rq_success / rq_total right after trigger === outbound|443||single-target.istio-vt-t14-r2.svc.cluster.local::10.255.126.10:8443::rq_error::0 outbound|443||single-target.istio-vt-t14-r2.svc.cluster.local::10.255.126.10:8443::rq_success::0 outbound|443||single-target.istio-vt-t14-r2.svc.cluster.local::10.255.126.10:8443::rq_total::0 outbound|80||single-target.istio-vt-t14-r2.svc.cluster.local::10.255.126.10:8080::rq_error::1 outbound|80||single-target.istio-vt-t14-r2.svc.cluster.local::10.255.126.10:8080::rq_success::1 outbound|80||single-target.istio-vt-t14-r2.svc.cluster.local::10.255.126.10:8080::rq_total::2 === CMD5 (adapted): 15x request loop over ~15s (well within baseEjectionTime 20s), using SHORT service name per corrected DNS rule === start=2026-07-05T00:59:00Z 15 200 end=2026-07-05T00:59:16Z === raw per-request sequence (order preserved) === 1 200 2 200 3 200 4 200 5 200 6 200 7 200 8 200 9 200 10 200 11 200 12 200 13 200 14 200 15 200 === immediately after loop: health_flags + counters (still within baseEjectionTime=20s from trigger?) === check_time=2026-07-05T00:59:28Z outbound|80||single-target.istio-vt-t14-r2.svc.cluster.local::10.255.126.10:8080::rq_error::1 outbound|80||single-target.istio-vt-t14-r2.svc.cluster.local::10.255.126.10:8080::rq_success::16 outbound|80||single-target.istio-vt-t14-r2.svc.cluster.local::10.255.126.10:8080::rq_total::17 outbound|80||single-target.istio-vt-t14-r2.svc.cluster.local::10.255.126.10:8080::health_flags::healthy === cluster-wide outlier_detection ejections_active stat === === full outlier_detection stats (including zeros) for context === === confirm state healthy before re-trigger === status=200 outbound|80||single-target.istio-vt-t14-r2.svc.cluster.local::10.255.126.10:8080::health_flags::healthy outbound|443||single-target.istio-vt-t14-r2.svc.cluster.local::10.255.126.10:8443::health_flags::healthy === CMD-interleaved: single exec session -- trigger real upstream 5xx, then 15x (request + health_flags) pairs at ~1s cadence, all within one shell to minimize timing slop === t0=1783213231. trigger_response=503 trigger_done_at=1783213231. post_trigger_flag: outbound|80||single-target.istio-vt-t14-r2.svc.cluster.local::10.255.126.10:8080::health_flags::/failed_outlier_check (1783213231.) iter=1 time=1783213231. status=503 health_flags::/failed_outlier_check iter=2 time=1783213232. status=503 health_flags::/failed_outlier_check iter=3 time=1783213233. status=503 health_flags::/failed_outlier_check iter=4 time=1783213234. status=503 health_flags::/failed_outlier_check iter=5 time=1783213235. status=503 health_flags::/failed_outlier_check iter=6 time=1783213236. status=503 health_flags::/failed_outlier_check iter=7 time=1783213237. status=503 health_flags::/failed_outlier_check iter=8 time=1783213238. status=503 health_flags::/failed_outlier_check iter=9 time=1783213239. status=503 health_flags::/failed_outlier_check iter=10 time=1783213240. status=503 health_flags::/failed_outlier_check iter=11 time=1783213241. status=503 health_flags::/failed_outlier_check iter=12 time=1783213242. status=503 health_flags::/failed_outlier_check iter=13 time=1783213243. status=503 health_flags::/failed_outlier_check iter=14 time=1783213244. status=503 health_flags::/failed_outlier_check iter=15 time=1783213245. status=503 health_flags::/failed_outlier_check === inspect actual response body/headers during ejection window (to distinguish Envoy-local 'no healthy upstream' vs real app 503) === --- verbose response --- HTTP/1.1 200 OK x-powered-by: Express content-type: application/json; charset=utf-8 content-length: 788 etag: W/"314-Lb+L1J2Ot5nDn3ynkfumYEQWrLo" date: Sun, 05 Jul 2026 01:01:39 GMT x-envoy-upstream-service-time: 4 server: envoy --- body --- { "path": "/", "headers": { "host": "single-target.istio-vt-t14-r2", "user-agent": "curl/8.14.1", "accept": "*/*", "x-forwarded-proto": "http", "x-request-id": "f0682777-a284-4d5b-b624-cf2e2fb9408e", "x-envoy-attempt-count": "1", "x-forwarded-client-cert": "By=spiffe://cluster.local/ns/istio-vt-t14-r2/sa/default;Hash=730bfffca9efcca113e8ceeab9d7f96e5a313abf284010692a1b29e74b6c1ee9;Subject=\"\";URI=spiffe://cluster.local/ns/istio-vt-t14-r2/sa/default" }, "method": "GET", "body": "", "fresh": false, "hostname": "single-target.istio-vt-t14-r2", "ip": "::ffff:127.0.0.6", "ips": [], "protocol": "http", "query": {}, "subdomains": [], "xhr": false, "os": { "hostname": "single-target-6fd9ff55b8-hxzvw" }, "connection": {} } --- current health_flags --- outbound|80||single-target.istio-vt-t14-r2.svc.cluster.local::10.255.126.10:8080::health_flags::healthy outbound|443||single-target.istio-vt-t14-r2.svc.cluster.local::10.255.126.10:8443::health_flags::healthy === FINAL run: trigger + interleaved (full response detail + health_flags), single atomic exec session === trigger_at=2026-07-05T01:01:55. trigger_status=503 iter=1 time=01:01:55. status_line=[HTTP/1.1 503 Service Unavailable ] has_upstream_hdr=0 80||single-target.istio-vt-t14-r2.svc.cluster.local::10.255.126.10:8080::health_flags::/failed_outlier_check iter=2 time=01:01:56. status_line=[HTTP/1.1 503 Service Unavailable ] has_upstream_hdr=0 80||single-target.istio-vt-t14-r2.svc.cluster.local::10.255.126.10:8080::health_flags::/failed_outlier_check iter=3 time=01:01:57. status_line=[HTTP/1.1 503 Service Unavailable ] has_upstream_hdr=0 80||single-target.istio-vt-t14-r2.svc.cluster.local::10.255.126.10:8080::health_flags::/failed_outlier_check iter=4 time=01:01:58. status_line=[HTTP/1.1 503 Service Unavailable ] has_upstream_hdr=0 80||single-target.istio-vt-t14-r2.svc.cluster.local::10.255.126.10:8080::health_flags::/failed_outlier_check iter=5 time=01:01:59. status_line=[HTTP/1.1 503 Service Unavailable ] has_upstream_hdr=0 80||single-target.istio-vt-t14-r2.svc.cluster.local::10.255.126.10:8080::health_flags::/failed_outlier_check iter=6 time=01:02:00. status_line=[HTTP/1.1 503 Service Unavailable ] has_upstream_hdr=0 80||single-target.istio-vt-t14-r2.svc.cluster.local::10.255.126.10:8080::health_flags::/failed_outlier_check iter=7 time=01:02:01. status_line=[HTTP/1.1 503 Service Unavailable ] has_upstream_hdr=0 80||single-target.istio-vt-t14-r2.svc.cluster.local::10.255.126.10:8080::health_flags::/failed_outlier_check iter=8 time=01:02:02. status_line=[HTTP/1.1 503 Service Unavailable ] has_upstream_hdr=0 80||single-target.istio-vt-t14-r2.svc.cluster.local::10.255.126.10:8080::health_flags::/failed_outlier_check iter=9 time=01:02:03. status_line=[HTTP/1.1 503 Service Unavailable ] has_upstream_hdr=0 80||single-target.istio-vt-t14-r2.svc.cluster.local::10.255.126.10:8080::health_flags::/failed_outlier_check iter=10 time=01:02:04. status_line=[HTTP/1.1 503 Service Unavailable ] has_upstream_hdr=0 80||single-target.istio-vt-t14-r2.svc.cluster.local::10.255.126.10:8080::health_flags::/failed_outlier_check iter=11 time=01:02:05. status_line=[HTTP/1.1 503 Service Unavailable ] has_upstream_hdr=0 80||single-target.istio-vt-t14-r2.svc.cluster.local::10.255.126.10:8080::health_flags::/failed_outlier_check iter=12 time=01:02:07. status_line=[HTTP/1.1 503 Service Unavailable ] has_upstream_hdr=0 80||single-target.istio-vt-t14-r2.svc.cluster.local::10.255.126.10:8080::health_flags::/failed_outlier_check iter=13 time=01:02:08. status_line=[HTTP/1.1 503 Service Unavailable ] has_upstream_hdr=0 80||single-target.istio-vt-t14-r2.svc.cluster.local::10.255.126.10:8080::health_flags::/failed_outlier_check iter=14 time=01:02:09. status_line=[HTTP/1.1 503 Service Unavailable ] has_upstream_hdr=0 80||single-target.istio-vt-t14-r2.svc.cluster.local::10.255.126.10:8080::health_flags::/failed_outlier_check iter=15 time=01:02:10. status_line=[HTTP/1.1 503 Service Unavailable ] has_upstream_hdr=0 80||single-target.istio-vt-t14-r2.svc.cluster.local::10.255.126.10:8080::health_flags::/failed_outlier_check iter=16 time=01:02:11. status_line=[HTTP/1.1 503 Service Unavailable ] has_upstream_hdr=0 80||single-target.istio-vt-t14-r2.svc.cluster.local::10.255.126.10:8080::health_flags::/failed_outlier_check iter=17 time=01:02:12. status_line=[HTTP/1.1 503 Service Unavailable ] has_upstream_hdr=0 80||single-target.istio-vt-t14-r2.svc.cluster.local::10.255.126.10:8080::health_flags::/failed_outlier_check iter=18 time=01:02:13. status_line=[HTTP/1.1 503 Service Unavailable ] has_upstream_hdr=0 80||single-target.istio-vt-t14-r2.svc.cluster.local::10.255.126.10:8080::health_flags::/failed_outlier_check === body of one of the 503 responses captured during the interleaved loop (iter=10 saved to /tmp/b_10.txt in pod) === no healthy upstream --- full response with -D- (fresh curl right now, likely already recovered) --- HTTP/1.1 200 OK x-powered-by: Express content-type: application/json; charset=utf-8 content-length: 788 etag: W/"314-A4goryjgpgyWbXS8+yLtW6i1t5g" date: Sun, 05 Jul 2026 01:02:24 GMT x-envoy-upstream-service-time: 4 server: envoy { "path": "/", "headers": { "host": "single-target.istio-vt-t14-r2", "user-agent": "curl/8.14.1", "accept": "*/*", "x-forwarded-proto": "http", "x-request-id": "cdcee8bf-e879-4252-b887-3c9a31b973ca", "x-envoy-attempt-count": "1", "x-forwarded-client-cert": "By=spiffe://cluster.local/ns/istio-vt-t14-r2/sa/default;Hash=730bfffca9efcca113e8ceeab9d7f96e5a313abf284010692a1b29e74b6c1ee9;Subject=\"\";URI=spiffe://cluster.local/ns/istio-vt-t14-r2/sa/default" }, === SUMMARY OF FINAL (unconfounded) INTERLEAVED OBSERVATION === During the 2026-07-05T01:01:55Z trigger's ejection window (health_flags remained '/failed_outlier_check' continuously for iter=1..18, spanning ~18s, well within baseEjectionTime=20s): 18/18 requests received HTTP 503 with body 'no healthy upstream' and NO x-envoy-upstream-service-time header (i.e. Envoy never proxied to the upstream -- this is Envoy's own local reply when the cluster has zero healthy hosts to route to). Once health_flags naturally reverted to 'healthy' (~20s later), requests immediately resumed getting real 200 responses WITH x-envoy-upstream-service-time and JSON echo body. => Envoy's LB panic threshold did NOT override the ejection for this single-endpoint cluster. Ejecting the sole endpoint = total traffic blackout for the full baseEjectionTime, exactly as the 'total block' claim (pass_criteria branch 1) predicts. === METHODOLOGY NOTE: naive literal replication of the spec's separate-exec command sequence (apply -> trigger -> check -> loop, each a distinct kubectl exec) reintroduces a NEW timing confound: kubectl exec round-trip latency (several seconds across ~4 separate execs) can consume enough of the 20s baseEjectionTime window that the loop starts near or after the ejection has already naturally expired, producing a false 'all 200' (panic-rescue -looking) result that is actually just 'ejection already over'. Confirmed for this run: a first attempt using literal separate-exec cadence returned all 15/15 200, but a post-hoc check showed health_flags had already reverted to healthy -- i.e. that first attempt's success was NOT evidence of panic-threshold rescue, just post-recovery traffic. FIX: collapse trigger+loop+health-flag-check into ONE kubectl exec/shell session (curl container shares pod netns with istio-proxy, so it can reach localhost:15000 directly) to eliminate inter-exec latency and keep the whole 15-18 iteration observation inside the genuine ejection window. This is the result reported as authoritative above. === CLEANUP: delete namespace istio-vt-t14-r2 (--wait=false) === namespace "istio-vt-t14-r2" deleted