lookout state gateway
When traffic through the Gateway API does not arrive — walk GatewayClass → Gateway → listener → HTTPRoute → Service and report every hop that is rejected, unprogrammed, or points at something that is not there. Silent, and cheap, on clusters without the Gateway API installed.
MCP tool: k8s_gateway_routes
lookout state gateway [flags]Common flags (every lookout command)
Section titled “Common flags (every lookout command)”| Flag | Type | Default | Meaning |
|---|---|---|---|
--namespace | string | — | limit the scan to one namespace |
-A | bool | — | scan all namespaces |
--workload | string | — | target one workload as <Kind>/<namespace>/<name>, e.g. Deployment/prod/api |
--since | duration | — | how far back to look (0 = command default) |
--format | string | logfmt | output format: logfmt|json (one record per line either way) |
--timeout | duration | 10s | abort the invocation after this long (exit 1) |
--kubeconfig | string | — | path to a kubeconfig file, instead of $KUBECONFIG / ~/.kube/config |
--context | string | — | kubeconfig context to read, instead of its current-context. Selects a cluster for THIS invocation only — nothing is written back — so concurrent invocations can target different clusters. Reported as context=<name> in the summary line |
--exemptions | string | — | path to a git-reviewed exemption file (YAML); covered findings are ANNOTATED with their reason and expiry and counted as exempt=<n> in the summary, never dropped |
Finding kinds
Section titled “Finding kinds”Every kind= this command can emit, and the severities it carries them at. Nothing else appears in its output; a kind absent from a run means the check looked and found nothing. See the finding-kind glossary for the whole vocabulary.
| Kind | Severity | Claim |
|---|---|---|
gateway.missing_class | critical | the Gateway names a GatewayClass that does not exist — nothing will program it |
gateway.class_not_accepted | critical | the Gateway’s GatewayClass is not Accepted by its controller |
gateway.not_accepted | critical | the Gateway itself is not Accepted |
gateway.not_programmed | critical | the Gateway is Accepted but not Programmed: no data plane is carrying its traffic |
gateway.listener_invalid | warning | one listener of an otherwise working Gateway is not resolved or not programmed |
route.missing_parent | critical | the route’s parentRef names a Gateway that does not exist |
route.not_accepted | critical | the Gateway refused the route’s attachment (listener, hostname, or namespace policy) |
route.missing_backend | critical | the route’s backendRef Service does not exist |
route.backend_port | critical | the route’s backendRef Service exists but does not expose the named port |
crd.unavailable | info | the API group this check reads is not served by the cluster, so nothing was examined (no coverage lies) |
Output fields
Section titled “Output fields”Beyond the shared envelope fields (kind, severity, namespace, kind_of_object, name, reason, message, fingerprint, exempt_reason, exempt_expires):
| Field | Meaning |
|---|---|
gateway_class | GatewayClass the Gateway names |
controller | the GatewayClass’s spec.controllerName — which implementation owns it |
gateway | Gateway the route attaches to, as namespace/name |
listener | listener name within the Gateway |
port | listener port, or the backendRef port the Service does not expose |
protocol | listener protocol |
condition | the status condition that is not True |
service | backend Service the route names, as namespace/name |
service_ports | ports the backend Service does expose, sorted |
classes | GatewayClasses the cluster does have, sorted |
api_group | crd.unavailable: the API group-version this command needed |
resources | crd.unavailable: the resources it would have read |
unavailable | summary-line note: why the group could not be read (absent CRDs, or discovery denied) |
Output contract
Section titled “Output contract”Output: one finding per line (logfmt; —format=json for one JSON object
per line), keys in fixed order; healthy resources emit nothing. The final
line is always the summary: scanned=
Examples
Section titled “Examples”lookout state gatewaylookout state gateway --namespace=prodlookout state gateway --format=json