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

  1. Create each scope exactly once and pass the Scope to the watcher instead of calling CreateScope again
  2. Use unique scope names for custom watchers (avoid "ingress", "node", "service")
  3. Fix control flow so the constructor (e.g. NewNodeController/NewIngressController) is not called twice for the same controller instance
  4. 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

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


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