kubernetes/kops · error
duplicate scope: %q
Error message
duplicate scope: %q
What it means
CreateScope refuses to create a second scope with the same name. Scopes are singletons in DNSController.scopes and each carries its own Ready flag and record map, so re-creating one would break ready-tracking semantics; the controller returns this error instead.
Source
Thrown at dns-controller/pkg/dns/dnscontroller.go:664
}
for i := range l {
if l[i] != r[i] {
return false
}
}
return true
}
// CreateScope creates a scope object.
func (c *DNSController) CreateScope(scopeName string) (Scope, error) {
c.mutex.Lock()
defer c.mutex.Unlock()
s := c.scopes[scopeName]
if s != nil {
// We can't support this then we would need to change Ready to a counter
// (OK, so we could, but it's probably an error anyway)
return nil, fmt.Errorf("duplicate scope: %q", scopeName)
}
s = &DNSControllerScope{
ScopeName: scopeName,
Records: make(map[string][]Record),
parent: c,
Ready: false,
}
c.scopes[scopeName] = s
return s, nil
}
View on GitHub (pinned to 4c8573c808)
Solutions
- Create each scope exactly once and pass the Scope to the watcher instead of calling CreateScope again
- Use unique scope names for custom watchers (avoid "ingress", "node", "service")
- Fix control flow so the constructor (e.g. NewNodeController/NewIngressController) is not called twice for the same controller instance
- If restart semantics are needed, construct a new DNSController rather than reusing scopes
Example fix
// before (second init reuses name)
scope1, _ := dns.CreateScope("node")
scope2, err := dns.CreateScope("node") // duplicate scope
// after
scope, err := dns.CreateScope("node")
nodeCtl := NewNodeController(client, dns, internalTypes) // controller owns its scope; don't recreate Defensive patterns
Strategy: validation
Validate before calling
if c.scopes != nil {
if _, exists := existingScopes[scopeName]; exists {
return fmt.Errorf("refusing to initialize watchers twice for scope %q", scopeName)
}
} Type guard
func scopeExists(c *dns.DNSController, name string) bool {
// expose via AllScopes()/lookup in tests; treat as guard before CreateScope
return scopes[name] != nil
} Try / catch
scope, err := dns.CreateScope("node")
if err != nil {
if strings.Contains(err.Error(), "duplicate scope") {
klog.Warning("watchers already initialized; skipping")
return nil
}
return err
} Prevention
- Create each scope exactly once at controller startup
- Never reuse reserved scope names (node, ingress, service) in custom code
- Guard initialization with sync.Once in tests and reload paths
When it happens
Trigger: Calling dns.CreateScope("name") twice with the same scopeName on the same DNSController instance — e.g. initializeWatchers invoked twice, or two watcher constructors both requesting the same scope name.
Common situations: Running initializeWatchers more than once in tests or on SIGHUP reload; a custom watcher reusing the built-in "node", "ingress", or "service" scope name; accidental double-start of the controller.
Related errors
- error building dns scope: %v
- error building dns scope: %v
- DNS not implemented on azureCloud
- incorrect syntax for lifecyle-overrides, correct syntax is T
- unknown lifecycle %q, available lifecycle: %s
AI-assisted analysis of kubernetes/kops@4c8573c808 (2026-09-05).
Data as JSON: /api/errors/e428f5fd1125b6aa.
Report an issue: GitHub.