The Istio ingress gateway failed to start because two different Istio components tried to bind to the same network port, 80, in the inbound direction, leading to a port conflict.

Common Causes and Fixes

  1. Duplicate Istio Ingress Gateway Deployments:

    • Diagnosis: Check for multiple istio-ingressgateway deployments in the istio-system namespace:
      kubectl get deployments -n istio-system | grep istio-ingressgateway
      
      If you see more than one, this is likely the issue.
    • Fix: Delete the extraneous deployment(s). Be sure to identify the correct one to keep (usually the one with the most recent rollout or desired replica count).
      kubectl delete deployment istio-ingressgateway-<suffix> -n istio-system
      
      This resolves the conflict by ensuring only one instance of the ingress gateway is configured to listen on port 80.
    • Why it works: A Kubernetes Deployment manages Pods. If multiple deployments are trying to manage Pods that all want to bind to the same port, the kernel will reject subsequent attempts.
  2. Istio Ingress Gateway Service Bound to Wrong Namespace:

    • Diagnosis: Verify that the istio-ingressgateway service is in the istio-system namespace and that its selector correctly targets the istio-ingressgateway pods.
      kubectl get svc istio-ingressgateway -n istio-system -o yaml
      
      Look for metadata.namespace: istio-system and spec.selector. Ensure the selector matches the labels on your ingress gateway pods. Also, check if there’s another service with the same name or port in a different namespace that might be inadvertently routing traffic.
    • Fix: If the service is in the wrong namespace, delete and recreate it in istio-system or correct its namespace. If the selector is wrong, update the service’s selector to match the ingress gateway pods.
      kubectl delete svc istio-ingressgateway -n <wrong-namespace>
      kubectl apply -f <path-to-istio-ingressgateway-service-yaml> -n istio-system
      
      This ensures the ingress gateway service is correctly registered and points to the actual ingress gateway pods.
    • Why it works: The Service object in Kubernetes acts as an abstraction layer for Pods. If the service points to the wrong set of pods or is in the wrong namespace, Istio’s control plane won’t be able to manage the gateway correctly, and other components might try to use the same port thinking it’s available.
  3. External Load Balancer or Other Service Already Using Port 80:

    • Diagnosis: If your Istio ingress gateway is exposed via a LoadBalancer type service, check if an external load balancer (cloud provider managed) or another Kubernetes Service of type LoadBalancer is already configured to use port 80.
      kubectl get svc -A -o yaml | grep -B 5 'externalTrafficPolicy: Cluster' # Look for LoadBalancer services
      
      Also, check your cloud provider’s load balancer console.
    • Fix: Reconfigure the external load balancer or the conflicting Service to use a different port, or change the Istio ingress gateway service to use a different nodePort (if using NodePort or LoadBalancer with externalTrafficPolicy: Local) or a different external port.
      # Example: Change Istio gateway service to use a different external port (e.g., 8080)
      kubectl edit svc istio-ingressgateway -n istio-system
      # In the YAML, change:
      # - port: 80
      #   targetPort: 8080
      #   protocol: TCP
      #   name: http2
      # to:
      # - port: 8080
      #   targetPort: 8080
      #   protocol: TCP
      #   name: http2
      
      This avoids the conflict by ensuring only one entity is listening on the desired external IP and port 80.
    • Why it works: In cloud environments, LoadBalancer services often provision an actual external load balancer. If two services try to provision an external load balancer for the same IP and port, one will fail.
  4. Manual Port Binding by Another Application:

    • Diagnosis: Check if any other application or Pod in your cluster is directly binding to port 80 on the nodes where the Istio ingress gateway Pods are scheduled. This is less common with Kubernetes abstractions but can happen with bare-metal deployments or misconfigured applications.
      # On a node where an ingress gateway pod is running:
      sudo netstat -tulnp | grep ':80'
      
      Or, check kubectl get pods -o wide to see which nodes your ingress gateway pods are on, and then SSH into those nodes to run netstat.
    • Fix: Reconfigure the conflicting application to use a different port or to run within its own Pod with proper resource isolation.
      # Example: If a rogue process 'nginx' is on port 80
      sudo systemctl stop nginx
      sudo systemctl disable nginx
      
      This removes the unauthorized listener on port 80, freeing it up for the Istio ingress gateway.
    • Why it works: The operating system kernel enforces that only one process can listen on a specific IP address and port combination at a time.
  5. Incorrect Istio Operator Configuration or Customizations:

    • Diagnosis: If you are using Istio Operator, review the IstioOperator custom resource definition. Look for any explicit port configurations for the ingress gateway that might be causing it to bind to port 80 in a way that conflicts with other components.
      # Example IstioOperator snippet to inspect
      apiVersion: install.istio.io/v1alpha1
      kind: IstioOperator
      spec:
        components:
          ingressGateways:
          - name: istio-ingressgateway
            enabled: true
            k8s:
              ports:
              - port: 80
                targetPort: 8080 # Check these ports carefully
                protocol: HTTP
                name: http
              - port: 443
                targetPort: 8443
                protocol: HTTPS
                name: https
      
    • Fix: Adjust the ports section in your IstioOperator CR to avoid conflicts. For instance, if you only need HTTPS on the gateway, you might disable the HTTP port or change its binding.
      # Example: Disabling HTTP port if not needed
      spec:
        components:
          ingressGateways:
          - name: istio-ingressgateway
            enabled: true
            k8s:
              ports:
              # - port: 80 # Commented out or removed
              #   targetPort: 8080
              #   protocol: HTTP
              #   name: http
              - port: 443
                targetPort: 8443
                protocol: HTTPS
                name: https
      
      This ensures the operator configures the gateway precisely as intended, without unintended port bindings.
    • Why it works: The Istio Operator generates Kubernetes resources (Deployments, Services, etc.) based on the IstioOperator CR. Incorrect configuration here directly leads to incorrect resource definitions, causing the port conflict.
  6. Conflicting Gateway Resources in Istio:

    • Diagnosis: While less common for the ingress gateway Pod itself to fail to start due to this, it’s worth checking if you have multiple Gateway resources defined in Istio that are both configured to bind to port 80 on the istio-ingressgateway instance.
      kubectl get gateways --all-namespaces
      
      Examine the spec.selector and spec.servers.port for any Gateway resources targeting the istio-ingressgateway (or whichever gateway you’re using) on port 80.
    • Fix: Consolidate or modify the Gateway resources so that only one is responsible for port 80, or ensure they target different hosts if they must coexist.
      # Example: Consolidating hosts into a single Gateway
      apiVersion: networking.istio.io/v1beta1
      kind: Gateway
      metadata:
        name: my-gateway
        namespace: istio-system
      spec:
        selector:
          istio: ingressgateway # Targets the default ingress gateway
        servers:
        - port:
            number: 80
            name: http
            protocol: HTTP
          hosts:
          - "example.com" # Host 1
          - "another.com" # Host 2
        - port:
            number: 443
            name: https
            protocol: HTTPS
          tls:
            mode: SIMPLE
            credentialName: my-credential
          hosts:
          - "secure.example.com"
      
      This ensures that the ingress gateway’s internal configuration (which maps to Envoy listeners) is not trying to set up multiple identical listeners for the same port.
    • Why it works: Istio’s control plane translates Gateway resources into Envoy proxy configuration. If multiple Gateway resources attempt to configure the same listener (same port, same protocol, same host wildcard), Envoy might reject the configuration, or the resulting behavior can be unpredictable.

After resolving the port conflict, the next error you might encounter is related to TLS certificates if you were expecting HTTPS traffic, such as Error: cert :: <namespace>/<secret-name> is not valid.

Want structured learning?

Take the full Istio course →