Skip to content

Traffic diagnosis

yuriy edited this page Oct 21, 2026 · 2 revisions

Traffic diagnosis

"Why does this Service get no traffic?" Sextant walks the path traffic would take to a Service, an Ingress, a Gateway API route, a Traefik IngressRoute or a Contour HTTPProxy, link by link, and says where it stops and why, in plain words. It reads the cluster's objects only: no probe pod is started and no traffic is sent, and nothing is changed.

Contents: Open it · Reading the result · What is checked · Ingress controllers · Network policies · Limits

Open it

  • Diagnose in the actions of a Service, an Ingress, an HTTPRoute, a GRPCRoute, a Traefik IngressRoute or a Contour HTTPProxy (the ⋮ button on a row or the top of the details) opens the diagnosis in a dialog: "Why kind name gets no traffic".
  • The Diagnosis tab in the details of the same kinds shows the same, and stays up to date while it is open.

Reading the result

Each link of the path is one line with a status:

Status Meaning
OK This link works.
Warning It works, but something needs attention (only some pods are Ready, a certificate covers only some hosts, a deprecated annotation).
Broken Traffic stops here. The summary at the top says "Traffic stops here:" and the reason.
Unknown Sextant cannot tell from the objects (a list you may not read, a controller it does not know). Never rounded up to OK.

A path stops at its first broken link ("The checks after the broken link were not run."), but its siblings go on: each path of an Ingress and each backend of a route is checked on its own. Objects named in a line are links to their details.

What is checked

A Service

  • An ExternalName Service: that externalName is a DNS name (not an IP address, not a URL). No pods or policies are involved; Sextant does not resolve the name.
  • The selector: which pods it matches in the namespace. When none match, pods that have every label but one are named ("3 pods have every label of the selector except tier=web").
  • Ready pods, with the reasons the others are not ready (from the same rules as the Problems page); publishNotReadyAddresses is taken into account.
  • Ports: each Service port's targetPort, by number or by name, against the containers' ports and protocols.
  • EndpointSlices against the Ready pods, including terminating endpoints that still serve. A Service without a selector is checked through the EndpointSlices labelled kubernetes.io/service-name. A headless Service is understood, also one with a selector and no ports.
  • Network policies (see below).
  • How it is exposed: the cluster DNS name, node ports, externalTrafficPolicy: Local, the load balancer address (or how long it has been waiting for one, and why that usually happens), external IPs and session affinity.

An Ingress

  • Its IngressClass: spec.ingressClassName, the deprecated kubernetes.io/ingress.class annotation, or the default class; a missing class, no default or several defaults are explained. An Ingress that has an address although no class matches is a warning ("some controller has claimed it"), not a break.
  • Whether the controller runs (see Ingress controllers) and the address it published.
  • TLS: for each TLS entry, the certificate in its Secret — expired, not yet valid, or not covering the hosts. The certificate is read by Sextant's backend; the private key never reaches the window (as in cert-manager and certificates).
  • Each rule and path: the meaning of its pathType (Exact, Prefix, ImplementationSpecific), a path that looks like a regular expression under Prefix, the backend Service and port — then all the Service checks above.

An HTTPRoute or GRPCRoute

  • Its parent Gateways: whether each accepted the route and on which listeners, the Gateway's addresses and its own problems, as in the Gateway API section.
  • Each rule and backend: no backends, a redirect, weight 0, a backend the controller refused (for example a missing ReferenceGrant), the backend Service and port — then the Service checks.

A Traefik IngressRoute (see Ecosystem views)

  • Its entry points, with the note that Traefik writes no status, so Sextant cannot say whether Traefik accepted the route.
  • TLS: the certificate in the Secret, read by Sextant's backend as for an Ingress, against the hosts of the Host and HostSNI rules and tls.domains. A missing Secret, one without a valid certificate or one that does not cover a host are warnings, not breaks (Traefik serves a default certificate), and they do not stop the walk. A certificate resolver's certificate is unknown.
  • Each route: the rule, each middleware, and each service. A Service goes on into the Service checks above; a TraefikService is followed through its weighted, mirroring, highest-random-weight and failover children (4 levels, 30 services). A reference into another namespace is unknown, since it depends on Traefik's allowCrossNamespace setting.
  • IngressRouteTCP and UDP are not diagnosed.

A Contour HTTPProxy (see Ecosystem views)

  • Contour's own state first: a proxy Contour rejected stops the walk, one it serves in part gets a warning and the walk goes on.
  • For a root: the host and the address Contour reports, the delegation and the certificate (read as for an Ingress).
  • For each route, each service with a share above 0 (or a mirror): that the Service exists in the proxy's namespace, then the Service checks. For each include: that it exists, is not a root and makes no cycle, its own state, and its routes and includes, up to 3 levels down and 30 services.
  • An include in a namespace the diagnosis does not read is unknown, never fine. Contour's --root-namespaces flag is invisible to Sextant.

Ingress controllers

Sextant finds a controller's pods only for controllers whose usual installation labels them in a known way: ingress-nginx, NGINX Ingress Controller, Traefik and the AWS Load Balancer Controller. For any other controller the step is Unknown, unless the controller published an address for the Ingress (then it clearly handles it).

Controllers that configure a load balancer outside the cluster (AWS ALB, GCE, Azure Application Gateway) keep the controller step, but traffic is taken to come from outside, not from the controller's pods.

Network policies

The last step asks whether network policies let the traffic into the backend pods, with the Connectivity engine (Kubernetes NetworkPolicies, Cilium and Calico policies). The traffic is taken to come from the known controller's pods, or else from a client outside the namespace. A rule that admits only some sources makes the answer "depends on which client it is". The line names the policy and rule that allow or deny; network policies have an effect only when the cluster's network plugin enforces them.

Limits

  • The answer comes from objects, never from live traffic: a process that does not listen on its port, a broken application or a cloud firewall are not seen.
  • At most 4 namespaces are read for one diagnosis (the object's own, its backends' and its parents'), and at most 8 TLS Secrets of an Ingress.
  • Traefik and Contour diagnoses are for the window only: AI agents cannot ask for them.
  • What you may not read is Unknown, not empty.
  • AI agents can ask for the same diagnosis with the diagnose_service tool (see MCP server); for them a TLS step also needs Secret values on Secrets of that namespace.

Next: Connectivity, Gateway API, Ecosystem views, Using Sextant.

Clone this wiki locally