Fix Istio Sidecar Injection Not Working
The Symptom
You deploy a pod in a namespace that should have Istio sidecar injection, but the pod starts with only one container instead of two. Running kubectl describe pod shows no istio-proxy container:
kubectl get pods -n my-app
# NAME READY STATUS RESTARTS AGE
# my-app-7d8f9b6c5-x2k4l 1/1 Running 0 30s
The expected output should show 2/2 (your app container plus the Envoy sidecar).
Root Cause
Istio's automatic sidecar injection relies on a Kubernetes mutating admission webhook. When a pod is created, the API server calls the webhook, which patches the pod spec to add the istio-proxy container. Injection fails when:
- The namespace is not labeled for injection.
- The pod or deployment has an annotation explicitly disabling injection.
- The
istio-sidecar-injectorwebhook is misconfigured or not running. - The pod is created by a controller that bypasses admission (rare).
Step-by-Step Fix
1. Check the namespace label
kubectl get namespace my-app --show-labels
You need the injection label. The required label depends on your Istio version:
# Istio 1.17+ (recommended)
kubectl label namespace my-app istio-injection=enabled
# For Istio with revision-based installs
kubectl label namespace my-app istio.io/rev=default
2. Check for opt-out annotations on the pod
Look at the deployment or pod template:
kubectl get deployment my-app -n my-app -o yaml | grep -A2 "sidecar.istio.io"
If you see sidecar.istio.io/inject: "false", remove it:
kubectl patch deployment my-app -n my-app --type=json \
-p='[{"op":"remove","path":"/spec/template/metadata/annotations/sidecar.istio.io~1inject"}]'
3. Verify the webhook is running
kubectl get mutatingwebhookconfiguration | grep istio
kubectl get pods -n istio-system -l app=sidecar-injector
If the injector pod is not running or is in CrashLoopBackOff, check its logs:
kubectl logs -n istio-system -l app=istiod -c discovery --tail=50
4. Verify the webhook configuration matches your namespace selector
kubectl get mutatingwebhookconfiguration istio-sidecar-injector -o yaml
Look at the namespaceSelector field. It should match the label you applied in step 1. If your cluster uses a revision-based install, the webhook may look for istio.io/rev instead of istio-injection.
5. Restart the deployment to trigger injection
Sidecar injection only happens at pod creation time. Existing pods will not be patched. Force a rollout:
kubectl rollout restart deployment my-app -n my-app
6. Verify injection succeeded
kubectl get pods -n my-app
# NAME READY STATUS RESTARTS AGE
# my-app-5f6a8b3d2-m9n7p 2/2 Running 0 15s
Confirm the sidecar is present:
kubectl describe pod -n my-app -l app=my-app | grep "istio-proxy"
Prevention Tips
- Label namespaces in your IaC. Define the
istio-injection=enabledlabel in your Terraform or Helm namespace definitions so new environments are always configured correctly. - Use
istioctl analyzeregularly. This command catches misconfigurations like missing labels or conflicting annotations before they cause issues. - Avoid blanket opt-out annotations. If a specific pod must skip injection (e.g., a job), annotate only that pod rather than the entire deployment.
- Pin your Istio revision. Revision-based installs let you upgrade Istio without affecting running workloads and make webhook selector behavior more predictable.
Was this article helpful?
Related Articles
Istio Pilot Discovery XDS Push Errors: Fixing "No Healthy Upstream" In Multi-Cluster Mesh Deployments
Quick reference for debugging `no healthy upstream` errors caused by Pilot xDS push failures in multi-cluster Istio setups. --- You're running a multi-clus...
Istio Gateway Returns 503 Service Unavailable: Debugging VirtualService And DestinationRule Misconfigurations
Nothing ruins your day quite like a 503 Service Unavailable error when you've spent hours configuring your shiny new Istio service mesh. I've been there mo...
Istio Installation & Architecture: Your First Service Mesh
Install Istio on Kubernetes, understand the control plane architecture, deploy your first sidecar proxy, and configure namespace injection.
Istio AuthorizationPolicy For Namespace-Level RBAC In Multi-Tenant Kubernetes Clusters
Multi-tenancy in Kubernetes is one of those topics that sounds straightforward until you're three months into a production incident because Team A's micros...
Istio EnvoyFilter Custom Configuration For Advanced HTTP Header Manipulation
Let's be honest: if you're running a service mesh in production, you're going to need custom header manipulation. Whether it's adding security headers, tra...
Istio mTLS & Security: Zero-Trust Service Communication
Enable mutual TLS in Istio, configure PeerAuthentication and AuthorizationPolicy, and secure service-to-service communication with zero-trust principles.
More in Istio
View all →Istio Observability: Kiali, Jaeger, and Prometheus Integration
Leverage Istio's built-in observability — Kiali service graph, Jaeger distributed tracing, Prometheus metrics, and Grafana dashboards for your service mesh.
Istio Traffic Management: Routing, Canary, and Circuit Breaking
Configure Istio VirtualServices, DestinationRules, and Gateways for advanced traffic routing, canary deployments, fault injection, and circuit breaking.