The Kubernetes API server is unable to route traffic to your backend pods because the network policy is blocking it.

Common Causes and Fixes

1. Incorrect Pod Selector in Service Definition

  • Diagnosis:

    kubectl get service <your-service-name> -o yaml
    

    Look for the selector field. Then, check your pod labels:

    kubectl get pods --show-labels
    

    Ensure the selector in your service exactly matches the labels on your target pods.

  • Fix: Edit your service:

    kubectl edit service <your-service-name>
    

    Update the selector to match your pod labels. For example, if your pods have app: my-app and tier: backend, your selector should be:

    selector:
      app: my-app
      tier: backend
    
  • Why it works: The service uses this selector to discover which pods are its endpoints. A mismatch means the service doesn’t know where to send traffic.

2. Pods Not Ready or Not Running

  • Diagnosis:

    kubectl get pods -l app=<your-app-label> -o wide
    

    Check the STATUS column. Pods should be Running and have READY counts greater than 0 (e.g., 1/1). If pods are Pending, CrashLoopBackOff, or Error, investigate those specific pods.

  • Fix: If pods are not running correctly, troubleshoot them individually:

    kubectl describe pod <pod-name>
    kubectl logs <pod-name>
    

    Address issues like image pull errors, configuration problems, or application crashes. Once pods are Running and Ready, the service will discover them.

  • Why it works: Services only send traffic to pods that are healthy and ready to receive requests. Unready pods are excluded from the service’s endpoint list.

3. Network Policy Blocking Traffic

  • Diagnosis: If you have NetworkPolicies applied, they might be preventing ingress to your pods.

    kubectl get networkpolicy -n <your-namespace>
    

    If policies exist, examine them:

    kubectl get networkpolicy <policy-name> -n <your-namespace> -o yaml
    

    Look for podSelector and ingress rules. Ensure there’s a rule allowing traffic from the source (e.g., other pods, the API server) to your backend pods on the correct port.

  • Fix: Add or modify a NetworkPolicy to allow traffic. For example, to allow ingress from all pods in the same namespace to pods with label app: backend on port 8080:

    apiVersion: networking.k8s.io/v1
    kind: NetworkPolicy
    metadata:
      name: allow-all-ingress-to-backend
      namespace: <your-namespace>
    spec:
      podSelector:
        matchLabels:
          app: backend
      policyTypes:
      - Ingress
      ingress:
      - from:
        - podSelector: {} # Allows from any pod in the namespace
        ports:
        - protocol: TCP
          port: 8080
    

    Apply it:

    kubectl apply -f <your-policy-file.yaml>
    
  • Why it works: NetworkPolicies act as firewalls at the pod level. Without explicit allow rules, traffic is denied by default.

4. Incorrect targetPort in Service Definition

  • Diagnosis: Check your service definition:

    kubectl get service <your-service-name> -o yaml
    

    Verify the targetPort in the ports section. Then, check the port your application is actually listening on inside the pod:

    kubectl exec <pod-name> -c <container-name> -- ss -tulnp
    # or
    kubectl exec <pod-name> -c <container-name> -- netstat -tulnp
    
  • Fix: Edit your service:

    kubectl edit service <your-service-name>
    

    Ensure targetPort matches the port your application listens on. If your app listens on 8080, and you want the service to be accessible on 80:

    ports:
    - port: 80
      targetPort: 8080 # This must match the application's listening port
      protocol: TCP
      name: http
    
  • Why it works: The targetPort is the port on the pod that the service’s port forwards traffic to. If they don’t match, traffic never reaches the application.

5. CNI Plugin Issues (e.g., Calico, Flannel, Cilium)

  • Diagnosis: Check the status of your CNI pods in the kube-system namespace:

    kubectl get pods -n kube-system -l k8s-app=<cni-app-label>
    

    (e.g., k8s-app=calico-node, app=flannel). They should all be Running. If not, check their logs and describe them for errors. Also, check your cluster’s node status:

    kubectl get nodes
    

    All nodes should be Ready.

  • Fix: Troubleshoot the specific CNI plugin. This often involves restarting CNI pods, checking their configuration files, or ensuring nodes have correct network connectivity and firewall rules. For example, if Calico pods are crashing, you might look at kubectl logs <calico-pod-name> -n kube-system and search for network configuration errors.

  • Why it works: The CNI plugin is responsible for network connectivity between pods across different nodes. If it’s misconfigured or unhealthy, pods cannot reach each other.

6. kube-proxy Not Running or Misconfigured

  • Diagnosis: kube-proxy is the component that implements Kubernetes Service networking. Check its status:

    kubectl get pods -n kube-system -l k8s-app=kube-proxy
    

    All kube-proxy pods should be Running. If not, inspect their logs and events.

  • Fix: If kube-proxy pods are unhealthy, restart them or investigate the underlying cause (e.g., resource constraints, configuration errors). Ensure its configuration (often managed by a ConfigMap) is correct for your cluster.

  • Why it works: kube-proxy programs the network rules (e.g., iptables, IPVS) on each node to manage Service IP routing and load balancing. If it’s not functioning, Services won’t be reachable.

The next error you’ll likely encounter if all these are fixed is an ERR_CONNECTION_REFUSED from your client, indicating the application inside the pod is not listening on the expected port, or a 503 Service Unavailable if the application itself is crashing.

Want structured learning?

Take the full Kubernetes course →