Introduction
Istio DestinationRule errors cause traffic routing failures when subsets are not found, load balancing policies are misconfigured, or traffic policies conflict with VirtualService rules. DestinationRules define how traffic is distributed to service versions, and errors in these configurations result in 503 errors, subset warnings, or unexpected traffic routing.
Symptoms
Error messages in Istio logs and istioctl:
DestinationRule subset not found: v1
No endpoints found for subset
Warning: DestinationRule references subset that VirtualService uses
Proxy: destination subset not availableObservable indicators: - istioctl analyze shows DestinationRule warnings - Traffic returns 503 No healthy upstream - Subset routing not working - Envoy cluster shows no endpoints - Services showing connection errors in logs
Common Causes
- 1.Subset label mismatch - Pod labels don't match subset selector
- 2.Missing DestinationRule - VirtualService references non-existent rule
- 3.Host mismatch - DestinationRule host different from VirtualService
- 4.TrafficPolicy conflict - Settings incompatible with service
- 5.OutlierDetection too aggressive - Ejecting healthy endpoints
- 6.ConnectionPool limits - Too restrictive, causing failures
- 7.Port mismatch - Service port different from DestinationRule
Step-by-Step Fix
Step 1: Analyze Configuration
```bash # Run istioctl analyze istioctl analyze
# Analyze specific namespace istioctl analyze -n production
# Get detailed analysis istioctl analyze --all-namespaces --output json
# Check for DestinationRule warnings istioctl analyze | grep -i destinationrule ```
Step 2: Check DestinationRule Configuration
```bash # List DestinationRules kubectl get destinationrules -A
# Describe specific DestinationRule kubectl describe destinationrule my-service -n production
# Get full configuration kubectl get destinationrule my-service -n production -o yaml
# Check host matching kubectl get destinationrule my-service -n production -o yamlpath='{.spec.host}' ```
Step 3: Check VirtualService References
```bash # List VirtualServices kubectl get virtualservices -A
# Check VirtualService destination kubectl get virtualservice my-service -n production -o yamlpath='{.spec.http[*].route[*].destination}'
# Verify subset references match DestinationRule kubectl get virtualservice my-service -n production -o yaml | grep subset ```
Step 4: Check Service and Pod Labels
```bash # Check service definition kubectl get service my-service -n production -o yaml
# Check pods and their labels kubectl get pods -n production -l app=my-service --show-labels
# Verify version labels match subset selectors kubectl get pods -n production -l app=my-service -o jsonpath='{range .items[*]}{.metadata.labels.version}{"\n"}{end}'
# Check endpoint slices kubectl get endpointslices -n production -l kubernetes.io/service-name=my-service ```
Step 5: Fix Subset Label Mismatch
# Correct DestinationRule with matching subset labels
apiVersion: networking.istio.io/v1beta1
kind: DestinationRule
metadata:
name: my-service
namespace: production
spec:
host: my-service
subsets:
- name: v1
labels:
version: v1 # Must match pod label
- name: v2
labels:
version: v2
trafficPolicy:
loadBalancer:
simple: ROUND_ROBIN```bash # Check pod labels match kubectl get pods -n production -l app=my-service,version=v1
# If missing, add version label kubectl label pods my-service-v1-xxx version=v1 -n production ```
Step 6: Fix Host Mismatch
```yaml # DestinationRule host must match VirtualService destination host apiVersion: networking.istio.io/v1beta1 kind: DestinationRule metadata: name: my-service spec: host: my-service # Simple name for same namespace # or: my-service.production.svc.cluster.local # FQN
--- apiVersion: networking.istio.io/v1beta1 kind: VirtualService metadata: name: my-service spec: hosts: - my-service # Must match DestinationRule host http: - route: - destination: host: my-service # Must match subset: v1 ```
Step 7: Fix TrafficPolicy Configuration
# Proper traffic policy configuration
apiVersion: networking.istio.io/v1beta1
kind: DestinationRule
metadata:
name: my-service
spec:
host: my-service
trafficPolicy:
connectionPool:
tcp:
maxConnections: 100
http:
h2UpgradePolicy: UPGRADE
http1MaxPendingRequests: 100
http2MaxRequests: 1000
outlierDetection:
consecutive5xxErrors: 10
interval: 30s
baseEjectionTime: 30s
maxEjectionPercent: 50
loadBalancer:
simple: ROUND_ROBIN
tls:
mode: ISTIO_MUTUALStep 8: Debug with istioctl proxy-config
```bash # Check Envoy cluster config istioctl proxy-config cluster deployment/my-app -n production
# Check specific cluster istioctl proxy-config cluster deployment/my-app -n production --cluster my-service
# Check endpoint config istioctl proxy-config endpoint deployment/my-app -n production
# Check route config istioctl proxy-config route deployment/my-app -n production
# Check all listeners istioctl proxy-config listener deployment/my-app -n production ```
Step 9: Verify the Fix
```bash # Re-run analysis istioctl analyze -n production
# Check proxy status istioctl proxy-status
# Test traffic routing kubectl exec deployment/test-client -n production -- curl my-service/version
# Monitor for errors kubectl logs -f deployment/my-app -n production -c istio-proxy | grep -i destination ```
Advanced Diagnosis
Check Envoy Config Dump
```bash # Get full config dump istioctl proxy-config all deployment/my-app -n production -o json
# Check for cluster errors istioctl proxy-config cluster deployment/my-app -n production -o json | jq '.[] | select(.name | contains("my-service"))'
# Check subset endpoints istioctl proxy-config endpoint deployment/my-app -n production | grep my-service ```
Debug Authentication Issues
```bash # If using mTLS, check auth policies kubectl get peerauthentication -A
# Check DestinationRule TLS mode matches kubectl get destinationrule my-service -n production -o yamlpath='{.spec.trafficPolicy.tls.mode}'
# For STRICT mTLS, DestinationRule must use ISTIO_MUTUAL ```
Check Service Entry
```bash # If service is external, check ServiceEntry kubectl get serviceentry -A
# DestinationRule for external service apiVersion: networking.istio.io/v1beta1 kind: DestinationRule metadata: name: external-service spec: host: external.example.com trafficPolicy: tls: mode: SIMPLE # For external HTTPS ```
Monitor Outlier Detection
```bash # Check outlier detection metrics kubectl exec deployment/my-app -n production -c istio-proxy -- curl localhost:15000/stats | grep outlier
# View ejection status istioctl proxy-config endpoint deployment/my-app -n production -o json | jq '.[] | select(. outlierStatus!=null)' ```
Common Pitfalls
- Subset label not on pod - Pod missing version label
- Host namespace mismatch - DestinationRule host wrong format
- TLS mode conflict - STRICT policy with wrong DestinationRule TLS
- Connection pool too low - Limits causing request failures
- Outlier detection too aggressive - Healthy endpoints ejected
- Port subset override - Wrong port in subset traffic policy
- Missing service definition - Kubernetes service doesn't exist
Best Practices
```yaml # Complete DestinationRule example apiVersion: networking.istio.io/v1beta1 kind: DestinationRule metadata: name: my-service namespace: production spec: host: my-service.production.svc.cluster.local subsets: - name: v1 labels: version: v1 trafficPolicy: connectionPool: tcp: maxConnections: 100 http: http1MaxPendingRequests: 50 - name: v2 labels: version: v2 trafficPolicy: tls: mode: ISTIO_MUTUAL loadBalancer: simple: ROUND_ROBIN outlierDetection: consecutive5xxErrors: 5 interval: 30s baseEjectionTime: 30s maxEjectionPercent: 30 minHealthPercent: 25
--- apiVersion: networking.istio.io/v1beta1 kind: VirtualService metadata: name: my-service namespace: production spec: hosts: - my-service http: - match: - headers: version: exact: v2 route: - destination: host: my-service.production.svc.cluster.local subset: v2 - route: - destination: host: my-service.production.svc.cluster.local subset: v1 weight: 90 - destination: host: my-service.production.svc.cluster.local subset: v2 weight: 10 ```
Related Issues
- Envoy Cluster Unhealthy
- Istio VirtualService Route Not Matching
- Consul Connect Proxy Error
- HAProxy Backend Down