{"record":{"id":"72b06367753adfd9","repo":"kubernetes/kops","slug":"error-building-dns-scope-v","errorCode":null,"errorMessage":"error building dns scope: %v","messagePattern":"error building dns scope: (.+?)","errorType":"console","errorClass":null,"httpStatus":null,"severity":"error","filePath":"dns-controller/pkg/watchers/ingress.go","lineNumber":46,"sourceCode":"\t\"k8s.io/klog/v2\"\n\t\"k8s.io/kops/dns-controller/pkg/dns\"\n\t\"k8s.io/kops/dns-controller/pkg/util\"\n\t\"k8s.io/kops/upup/pkg/fi/utils\"\n)\n\n// IngressController watches for Ingress objects with dns labels\ntype IngressController struct {\n\tutil.Stoppable\n\tclient    kubernetes.Interface\n\tnamespace string\n\tscope     dns.Scope\n}\n\n// NewIngressController creates a IngressController\nfunc NewIngressController(client kubernetes.Interface, dns dns.Context, namespace string) (*IngressController, error) {\n\tscope, err := dns.CreateScope(\"ingress\")\n\tif err != nil {\n\t\treturn nil, fmt.Errorf(\"error building dns scope: %v\", err)\n\t}\n\tc := &IngressController{\n\t\tclient:    client,\n\t\tnamespace: namespace,\n\t\tscope:     scope,\n\t}\n\n\treturn c, nil\n}\n\n// Run starts the IngressController.\nfunc (c *IngressController) Run() {\n\tklog.Infof(\"starting ingress controller\")\n\n\tstopCh := c.StopChannel()\n\tgo c.runWatcher(stopCh)\n\n\t<-stopCh","sourceCodeStart":28,"sourceCodeEnd":64,"githubUrl":"https://github.com/kubernetes/kops/blob/4c8573c808a73d578c5eadc86d410646ea0b0d73/dns-controller/pkg/watchers/ingress.go#L28-L64","documentation":"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).","triggerScenarios":"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.","commonSituations":"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.","solutions":["Ensure initializeWatchers runs only once per DNSController lifetime","Create a fresh DNSController (dns.NewDNSController(...)) if restarting watchers","Pass the existing ingress Scope into the controller rather than recreating it","Check the wrapped %v cause; if it is the duplicate-scope error, look for the prior CreateScope(\"ingress\") call"],"exampleFix":"// before\ninitializeWatchers(...)\ninitializeWatchers(...) // second call -> duplicate scope\n// after\nrunOnce := sync.Once{}\nrunOnce.Do(func() { initializeWatchers(kubeClient, dns, watchNamespace) })","handlingStrategy":"try-catch","validationCode":"// ensure watchers initialize once\nvar initOnce sync.Once\nfunc ensureWatchers(client kubernetes.Interface, dnsCtx dns.Context, ns string) error {\n    var initErr error\n    initOnce.Do(func() { initErr = initializeWatchers(client, dnsCtx, ns) })\n    return initErr\n}","typeGuard":null,"tryCatchPattern":"ctl, err := watchers.NewIngressController(client, dnsContext, ns)\nif err != nil {\n    if strings.Contains(err.Error(), \"duplicate scope\") {\n        return nil // already initialized\n    }\n    return fmt.Errorf(\"starting ingress watcher: %w\", err)\n}","preventionTips":["Initialize watchers exactly once per DNSController (sync.Once)","Never call CreateScope(\"ingress\") outside NewIngressController","Build a new DNSController for restart/reload instead of reusing scopes"],"tags":["dns","scope","ingress","initialization"],"backgroundTag":"duplicate-scope-creation","analyzedSha":"4c8573c808a73d578c5eadc86d410646ea0b0d73","analyzedAt":"2026-09-05T04:13:19.212Z","contentChangedAt":"2026-09-05T04:13:19.212Z","schemaVersion":2},"datasetVersion":"2026-09-12T12:17:11.808Z"}