kubernetes/kops · error

error building dns scope: %v

Error message

error building dns scope: %v

What it means

NewIngressController wraps any failure from dns.CreateScope("ingress") with this message. Since CreateScope only fails on a duplicate scope name, this error means an "ingress" scope already exists on the DNSContext when the ingress watcher is constructed (e.g. initializeWatchers ran twice).

Source

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

	"k8s.io/klog/v2"
	"k8s.io/kops/dns-controller/pkg/dns"
	"k8s.io/kops/dns-controller/pkg/util"
	"k8s.io/kops/upup/pkg/fi/utils"
)

// IngressController watches for Ingress objects with dns labels
type IngressController struct {
	util.Stoppable
	client    kubernetes.Interface
	namespace string
	scope     dns.Scope
}

// NewIngressController creates a IngressController
func NewIngressController(client kubernetes.Interface, dns dns.Context, namespace string) (*IngressController, error) {
	scope, err := dns.CreateScope("ingress")
	if err != nil {
		return nil, fmt.Errorf("error building dns scope: %v", err)
	}
	c := &IngressController{
		client:    client,
		namespace: namespace,
		scope:     scope,
	}

	return c, nil
}

// Run starts the IngressController.
func (c *IngressController) Run() {
	klog.Infof("starting ingress controller")

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

	<-stopCh

View on GitHub (pinned to 4c8573c808)

Solutions

  1. Ensure initializeWatchers runs only once per DNSController lifetime
  2. Create a fresh DNSController (dns.NewDNSController(...)) if restarting watchers
  3. Pass the existing ingress Scope into the controller rather than recreating it
  4. Check the wrapped %v cause; if it is the duplicate-scope error, look for the prior CreateScope("ingress") call

Example fix

// before
initializeWatchers(...)
initializeWatchers(...) // second call -> duplicate scope
// after
runOnce := sync.Once{}
runOnce.Do(func() { initializeWatchers(kubeClient, dns, watchNamespace) })
Defensive patterns

Strategy: try-catch

Validate before calling

// ensure watchers initialize once
var initOnce sync.Once
func ensureWatchers(client kubernetes.Interface, dnsCtx dns.Context, ns string) error {
    var initErr error
    initOnce.Do(func() { initErr = initializeWatchers(client, dnsCtx, ns) })
    return initErr
}

Try / catch

ctl, err := watchers.NewIngressController(client, dnsContext, ns)
if err != nil {
    if strings.Contains(err.Error(), "duplicate scope") {
        return nil // already initialized
    }
    return fmt.Errorf("starting ingress watcher: %w", err)
}

Prevention

When it happens

Trigger: initializeWatchers calls NewIngressController while a scope named "ingress" was already created on the same dns.Context — typically a second call to initializeWatchers or reuse of a DNSController across restarts.

Common situations: Double initialization of watchers in main or tests; re-running watcher setup on config reload; custom code creating the "ingress" scope before constructing the controller.

Related errors


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