The Istio ingress gateway is refusing connections to your services because it can’t decide which DestinationRule to use for routing, leading to 503 errors.

This happens when multiple DestinationRule resources in your Istio control plane are defined with overlapping host fields, but have different configurations for subsets, traffic policies, or load balancing. The Istio ingress gateway, when processing incoming requests, encounters this ambiguity and cannot deterministically select a DestinationRule to apply, resulting in the connection being dropped.

Here are the most common causes and their fixes:

1. Duplicate DestinationRule Definitions for the Same Host

Diagnosis: List all DestinationRule resources in your Istio system and examine their host fields.

kubectl get destinationrules --all-namespaces -o jsonpath='{.items[*].metadata.namespace} {.items[*].metadata.name} {.items[*].spec.host}'

Look for identical host values across different DestinationRule objects.

Fix: Consolidate the conflicting DestinationRule resources into a single definition. If you need different configurations (e.g., subsets for different versions), define them within the subsets field of a single DestinationRule.

Example: Instead of:

apiVersion: networking.istio.io/v1alpha3
kind: DestinationRule
metadata:
  name: my-service-dr-v1
  namespace: default
spec:
  host: my-service.default.svc.cluster.local
  subsets:
  - name: v1
    labels:
      version: v1

and

apiVersion: networking.istio.io/v1alpha3
kind: DestinationRule
metadata:
  name: my-service-dr-v2
  namespace: default
spec:
  host: my-service.default.svc.cluster.local
  subsets:
  - name: v2
    labels:
      version: v2

Combine them:

apiVersion: networking.istio.io/v1alpha3
kind: DestinationRule
metadata:
  name: my-service-dr
  namespace: default
spec:
  host: my-service.default.svc.cluster.local
  subsets:
  - name: v1
    labels:
      version: v1
  - name: v2
    labels:
      version: v2

This works because a single DestinationRule can contain multiple subsets, allowing you to manage different versions or traffic policies for the same host in one place, eliminating the ambiguity for Istio.

2. Overlapping Wildcard Hosts

Diagnosis: Examine DestinationRule definitions for wildcard hosts (e.g., *.example.com or *.default.svc.cluster.local). Check if a more specific host rule exists that should take precedence. Istio’s host matching is based on longest prefix match, but complex overlaps can still cause issues.

Fix: Make wildcard rules more specific or remove redundant ones. If you have a DestinationRule for *.default.svc.cluster.local and another for my-service.default.svc.cluster.local, the latter should be preferred. Ensure the more specific rule is present and the broader one is either removed or adjusted.

Example: If you have:

apiVersion: networking.istio.io/v1alpha3
kind: DestinationRule
metadata:
  name: all-services-dr
  namespace: istio-system
spec:
  host: "*.default.svc.cluster.local" # Too broad
  trafficPolicy:
    loadBalancer:
      simple: ROUND_ROBIN

and

apiVersion: networking.istio.io/v1alpha3
kind: DestinationRule
metadata:
  name: my-service-dr
  namespace: default
spec:
  host: my-service.default.svc.cluster.local
  trafficPolicy:
    loadBalancer:
      simple: LEAST_REQUEST

Remove or modify all-services-dr to not conflict. If the ROUND_ROBIN policy is truly needed for all services, ensure it’s not overridden by a more specific rule. Often, broad wildcard rules are accidental.

3. Conflicting Subset Definitions within the Same Host

Diagnosis: Within a single DestinationRule for a given host, check if multiple subsets are defined with identical labels or name fields.

Fix: Ensure each subset within a DestinationRule has a unique name. If subsets are intended to target the same pods (e.g., by identical labels), ensure they are merged into a single subset definition or that their purposes are clearly distinct and named accordingly.

Example:

apiVersion: networking.istio.io/v1alpha3
kind: DestinationRule
metadata:
  name: my-service-dr
  namespace: default
spec:
  host: my-service.default.svc.cluster.local
  subsets:
  - name: v1-a # Duplicate name
    labels:
      version: v1
  - name: v1-b # Duplicate name
    labels:
      version: v1

Consolidate to:

apiVersion: networking.istio.io/v1alpha3
kind: DestinationRule
metadata:
  name: my-service-dr
  namespace: default
spec:
  host: my-service.default.svc.cluster.local
  subsets:
  - name: v1
    labels:
      version: v1

4. Namespace-Specific vs. Global DestinationRule Ambiguity

Diagnosis: Check if you have DestinationRule objects defined in both the service’s namespace and the Istio system namespace (often istio-system) that apply to the same host. Istio prioritizes DestinationRule in the service’s namespace.

Fix: If a DestinationRule in the istio-system namespace is intended to provide a global policy, ensure it doesn’t conflict with more specific DestinationRule objects in individual service namespaces. If a global policy is not needed, remove the conflicting DestinationRule from istio-system.

Example: A DestinationRule in istio-system might have:

apiVersion: networking.istio.io/v1alpha3
kind: DestinationRule
metadata:
  name: global-lb
  namespace: istio-system
spec:
  host: "my-service.default.svc.cluster.local"
  trafficPolicy:
    loadBalancer:
      simple: ROUND_ROBIN

And in the default namespace:

apiVersion: networking.istio.io/v1alpha3
kind: DestinationRule
metadata:
  name: my-service-dr
  namespace: default
spec:
  host: "my-service.default.svc.cluster.local"
  trafficPolicy:
    loadBalancer:
      simple: LEAST_REQUEST

The rule in the default namespace will take precedence. If ROUND_ROBIN was desired globally, the my-service-dr in default should be removed or modified to inherit from a global policy if such a pattern is supported by your Istio version and intended.

5. Incorrectly Configured Gateway Resources Referencing Non-Existent DestinationRules

Diagnosis: While this typically results in 503s from the gateway itself, it can manifest as routing issues if the Gateway is configured to route to a host for which no DestinationRule exists or is correctly applied. Check your Gateway resources for hosts and gateways fields and ensure they align with defined VirtualService and DestinationRule resources.

Fix: Ensure that every host specified in a Gateway resource that is intended to be routed has a corresponding VirtualService that then references a DestinationRule (or has its own traffic policies). If a DestinationRule is missing for a host used by a Gateway, create one.

6. Istio Version Incompatibilities or Bugs

Diagnosis: Check the Istio version you are running. Consult the Istio documentation and release notes for known issues related to DestinationRule parsing or conflict resolution in your specific version.

Fix: Upgrade to a stable, recommended version of Istio. If a bug is identified, apply any available patches or workarounds provided by the Istio community.

After resolving these conflicts, you might encounter 503 errors related to upstream services being unavailable if the underlying pods are not running or healthy, which is a separate issue from DestinationRule conflicts.

Want structured learning?

Take the full Istio course →