{"record":{"id":"7ad4e76fa67be7b1","repo":"kubernetes/kops","slug":"error-listing-ingresses-v","errorCode":null,"errorMessage":"error listing ingresses: %v","messagePattern":"error listing ingresses: (.+?)","errorType":"console","errorClass":null,"httpStatus":null,"severity":"error","filePath":"dns-controller/pkg/watchers/ingress.go","lineNumber":78,"sourceCode":"\n\tstopCh := c.StopChannel()\n\tgo c.runWatcher(stopCh)\n\n\t<-stopCh\n\tklog.Infof(\"shutting down ingress controller\")\n}\n\nfunc (c *IngressController) runWatcher(stopCh <-chan struct{}) {\n\trunOnce := func() (bool, error) {\n\t\tctx := context.TODO()\n\n\t\tvar listOpts metav1.ListOptions\n\t\tklog.V(4).Infof(\"querying without label filter\")\n\n\t\tallKeys := c.scope.AllKeys()\n\t\tingressList, err := c.client.NetworkingV1().Ingresses(c.namespace).List(ctx, listOpts)\n\t\tif err != nil {\n\t\t\treturn false, fmt.Errorf(\"error listing ingresses: %v\", err)\n\t\t}\n\t\tfoundKeys := make(map[string]bool)\n\t\tfor i := range ingressList.Items {\n\t\t\tingress := &ingressList.Items[i]\n\t\t\tklog.V(4).Infof(\"found ingress: %v\", ingress.Name)\n\t\t\tkey := c.updateIngressRecords(ingress)\n\t\t\tfoundKeys[key] = true\n\t\t}\n\t\tfor _, key := range allKeys {\n\t\t\tif !foundKeys[key] {\n\t\t\t\t// The ingress previously existed, but no longer exists; delete it from the scope\n\t\t\t\tklog.V(2).Infof(\"removing ingress not found in list: %s\", key)\n\t\t\t\tc.scope.Replace(key, nil)\n\t\t\t}\n\t\t}\n\t\tc.scope.MarkReady()\n\n\t\tlistOpts.Watch = true","sourceCodeStart":60,"sourceCodeEnd":96,"githubUrl":"https://github.com/kubernetes/kops/blob/4c8573c808a73d578c5eadc86d410646ea0b0d73/dns-controller/pkg/watchers/ingress.go#L60-L96","documentation":"The ingress watcher's runOnce loop failed to list Ingresses from the Kubernetes API (NetworkingV1().Ingresses(namespace).List) and wraps the client error. Without a successful list the watcher cannot reconcile DNS records, so it returns false to signal the loop should retry after the backoff.","triggerScenarios":"The k8s API request to list ingresses fails: RBAC denial (no list ingresses permission), API server unreachable, namespace doesn't exist, or invalid ListOptions.","commonSituations":"ClusterRole missing networking.k8s.io/ingresses list/get/watch; --watch-namespace pointing at a deleted namespace; API server temporarily down or certificate/expired-token issues; controller running outside the cluster with stale kubeconfig.","solutions":["Read the wrapped %v cause: Forbidden -> fix RBAC, connection refused -> check API server reachability, not found -> fix --watch-namespace","Grant the dns-controller service account list/watch on ingresses in the target namespace (or cluster-wide)","Verify kubeClient credentials/kubeconfig are valid and the namespace exists","Rely on the retry loop — transient API errors resolve on the next iteration"],"exampleFix":"// RBAC before: no ingress perms\n// after\nrules:\n- apiGroups: [\"networking.k8s.io\"]\n  resources: [\"ingresses\"]\n  verbs: [\"list\",\"watch\",\"get\"]","handlingStrategy":"retry","validationCode":"// preflight RBAC + namespace check before starting the watcher\nif _, err := client.NetworkingV1().Ingresses(namespace).Get(ctx, \"__probe__\", metav1.GetOptions{}); err != nil {\n    if apierrors.IsForbidden(err) { klog.Fatalf(\"SA lacks ingresses permissions in %s: %v\", namespace, err) }\n}\nif _, err := client.CoreV1().Namespaces().Get(ctx, namespace, metav1.GetOptions{}); err != nil {\n    klog.Fatalf(\"watch namespace %q unavailable: %v\", namespace, err)\n}","typeGuard":null,"tryCatchPattern":"ok, err := runOnce(ctx, c, listOpts)\nif err != nil {\n    if apierrors.IsForbidden(errors.Unwrap(err)) {\n        klog.Errorf(\"RBAC: grant list on ingresses to the dns-controller SA\")\n    } else {\n        klog.Warningf(\"transient: retrying: %v\", err)\n    }\n    return false, nil // outer loop retries with backoff\n}","preventionTips":["Grant list/watch/get on ingresses to the dns-controller service account","Verify --watch-namespace exists at startup","Use in-cluster credentials or a fresh kubeconfig","Rely on the built-in retry loop for transient API errors"],"tags":["kubernetes","ingress","rbac","api-client"],"backgroundTag":"kubernetes-api-list-failed","analyzedSha":"4c8573c808a73d578c5eadc86d410646ea0b0d73","analyzedAt":"2026-09-05T04:13:19.212Z","contentChangedAt":"2026-09-05T04:13:19.212Z","schemaVersion":2},"datasetVersion":"2026-09-12T07:17:12.445Z"}