kubernetes/kops · error

error listing ingresses: %v

Error message

error listing ingresses: %v

What it means

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.

Source

Thrown at dns-controller/pkg/watchers/ingress.go:78

	stopCh := c.StopChannel()
	go c.runWatcher(stopCh)

	<-stopCh
	klog.Infof("shutting down ingress controller")
}

func (c *IngressController) runWatcher(stopCh <-chan struct{}) {
	runOnce := func() (bool, error) {
		ctx := context.TODO()

		var listOpts metav1.ListOptions
		klog.V(4).Infof("querying without label filter")

		allKeys := c.scope.AllKeys()
		ingressList, err := c.client.NetworkingV1().Ingresses(c.namespace).List(ctx, listOpts)
		if err != nil {
			return false, fmt.Errorf("error listing ingresses: %v", err)
		}
		foundKeys := make(map[string]bool)
		for i := range ingressList.Items {
			ingress := &ingressList.Items[i]
			klog.V(4).Infof("found ingress: %v", ingress.Name)
			key := c.updateIngressRecords(ingress)
			foundKeys[key] = true
		}
		for _, key := range allKeys {
			if !foundKeys[key] {
				// The ingress previously existed, but no longer exists; delete it from the scope
				klog.V(2).Infof("removing ingress not found in list: %s", key)
				c.scope.Replace(key, nil)
			}
		}
		c.scope.MarkReady()

		listOpts.Watch = true

View on GitHub (pinned to 4c8573c808)

Solutions

  1. Read the wrapped %v cause: Forbidden -> fix RBAC, connection refused -> check API server reachability, not found -> fix --watch-namespace
  2. Grant the dns-controller service account list/watch on ingresses in the target namespace (or cluster-wide)
  3. Verify kubeClient credentials/kubeconfig are valid and the namespace exists
  4. Rely on the retry loop — transient API errors resolve on the next iteration

Example fix

// RBAC before: no ingress perms
// after
rules:
- apiGroups: ["networking.k8s.io"]
  resources: ["ingresses"]
  verbs: ["list","watch","get"]
Defensive patterns

Strategy: retry

Validate before calling

// preflight RBAC + namespace check before starting the watcher
if _, err := client.NetworkingV1().Ingresses(namespace).Get(ctx, "__probe__", metav1.GetOptions{}); err != nil {
    if apierrors.IsForbidden(err) { klog.Fatalf("SA lacks ingresses permissions in %s: %v", namespace, err) }
}
if _, err := client.CoreV1().Namespaces().Get(ctx, namespace, metav1.GetOptions{}); err != nil {
    klog.Fatalf("watch namespace %q unavailable: %v", namespace, err)
}

Try / catch

ok, err := runOnce(ctx, c, listOpts)
if err != nil {
    if apierrors.IsForbidden(errors.Unwrap(err)) {
        klog.Errorf("RBAC: grant list on ingresses to the dns-controller SA")
    } else {
        klog.Warningf("transient: retrying: %v", err)
    }
    return false, nil // outer loop retries with backoff
}

Prevention

When it happens

Trigger: The k8s API request to list ingresses fails: RBAC denial (no list ingresses permission), API server unreachable, namespace doesn't exist, or invalid ListOptions.

Common situations: 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.

Related errors


AI-assisted analysis of kubernetes/kops@4c8573c808 (2026-09-05). Data as JSON: /api/errors/7ad4e76fa67be7b1. Report an issue: GitHub.