A Systematic Approach
Mesh failures are frustrating because they are often silent — traffic either works or doesn't, with no obvious error message pointing to the proxy layer. The following scenarios cover the most common failure modes and how to diagnose them.
Scenario 1: "My Pod has no sidecar!"
Check the namespace's labels first — you need to see istio-injection=enabled. If it's missing, adding it enables injection going forward, but labeling the namespace does not inject sidecars into existing Pods. You must restart them.
Also check for an opt-out annotation on the Pod template itself: if sidecar.istio.io/inject is set to false, that Pod is explicitly excluded regardless of the namespace label.
Scenario 2: "My Pod is stuck in Init or CrashLoopBackOff!"
Check the istio-init container's own logs. Common causes: a PodSecurityPolicy (or Pod Security Admission) blocking NET_ADMIN capabilities, or a security context on the Pod that prevents the initContainer from running as root. The fix is to grant the necessary capabilities or use Istio's CNI plugin mode, which moves iptables setup out of the initContainer entirely (eliminating the need for NET_ADMIN).
Scenario 3: "Connection refused at startup!"
Your application starts and immediately tries to connect to another service, but gets Connection refused. This happens because the application starts before Envoy has finished bootstrapping and connecting to istiod to receive its configuration.
Fix: enable holdApplicationUntilProxyStarts in the mesh config's defaultConfig. This tells Envoy to delay the readiness of the Pod until the proxy is fully initialized, preventing the application from making outbound calls before the mesh is ready.
Scenario 4: "mTLS is failing between two services!"
istioctl's pod-describe command shows you exactly which PeerAuthentication and AuthorizationPolicy resources apply to a given Pod, and whether the mesh expects mTLS in STRICT, PERMISSIVE, or DISABLED mode. A common mistake is having one service in STRICT mode and its client in a namespace without a sidecar — the client sends plain text, and the server rejects it.
Interviewers often ask: "How do you debug a 503 error in a service mesh?" The answer should demonstrate layered thinking. Start at the data plane: istioctl proxy-config to inspect the sidecar's view of routes and clusters. Check if the upstream cluster has healthy endpoints (istioctl proxy-config endpoints). Then check the control plane: istioctl analyze to detect misconfigurations in VirtualService or DestinationRule resources. Finally, check Envoy access logs (enabled via meshConfig.accessLogFile) to see exactly what the proxy decided and why. Never start by blaming the application until you've ruled out the mesh.