kubernetes/kops · error

found multiple KubeSchedulerConfiguration objects in cluster

Error message

found multiple KubeSchedulerConfiguration objects in cluster configuration; expected at most one

What it means

buildSchedulerConfig scans b.AdditionalObjects for KubeSchedulerConfiguration objects (matching GVK) and requires at most one, since a single kube-scheduler component config is unambiguous. If more than one AdditionalObject has the KubeSchedulerConfiguration kind, the builder cannot pick one and returns this error.

Source

Thrown at pkg/model/components/kubescheduler/model.go:76

	})
	return nil
}

func (b *KubeSchedulerBuilder) buildSchedulerConfig() ([]byte, error) {
	var matches []*kubemanifest.Object
	for _, additionalObject := range b.AdditionalObjects {
		gvk := additionalObject.GroupVersionKind()
		if gvk.Group != "kubescheduler.config.k8s.io" {
			continue
		}
		if gvk.Kind != "KubeSchedulerConfiguration" {
			continue
		}
		matches = append(matches, additionalObject)
	}

	if len(matches) > 1 {
		return nil, fmt.Errorf("found multiple KubeSchedulerConfiguration objects in cluster configuration; expected at most one")
	}

	var config *unstructured.Unstructured
	if len(matches) == 1 {
		config = matches[0].ToUnstructured()
	} else {
		config = &unstructured.Unstructured{}
		config.SetKind("KubeSchedulerConfiguration")
		config.SetAPIVersion("kubescheduler.config.k8s.io/v1")
		// We need to store the object, because we are often called repeatedly (until we converge)
		b.AdditionalObjects = append(b.AdditionalObjects, kubemanifest.NewObject(config.Object))
	}

	// TODO: Handle different versions? e.g. gvk := config.GroupVersionKind()

	if err := unstructured.SetNestedField(config.Object, wellknownpaths.KubeSchedulerKubeConfig, "clientConnection", "kubeconfig"); err != nil {
		return nil, fmt.Errorf("error setting clientConnection.kubeconfig in kube-scheduler configuration: %w", err)
	}

View on GitHub (pinned to 4c8573c808)

Solutions

  1. Remove duplicate KubeSchedulerConfiguration objects from AdditionalObjects so only one remains
  2. Merge the two configs into a single KubeSchedulerConfiguration before passing it in
  3. Verify which addon/task adds the extra object (inspect b.AdditionalObjects before Build) and drop the redundant one

Example fix

// before
b.AdditionalObjects = append(b.AdditionalObjects, schedCfg1)
b.AdditionalObjects = append(b.AdditionalObjects, schedCfg2)
// after
b.AdditionalObjects = append(b.AdditionalObjects, mergedSchedCfg)
Defensive patterns

Strategy: validation

Validate before calling

count := 0
for _, o := range b.AdditionalObjects {
    if o.GetKind() == "KubeSchedulerConfiguration" {
        count++
    }
}
if count > 1 {
    return fmt.Errorf("%d KubeSchedulerConfiguration objects in AdditionalObjects; expected at most 1", count)
}

Prevention

When it happens

Trigger: Passing two or more AdditionalObjects of kind KubeSchedulerConfiguration (apiVersion kubescheduler.config.k8s.io) into the KubeScheduler builder and calling Build → buildSchedulerConfig, e.g. from addons or task inputs that each add a scheduler config.

Common situations: A cluster addon and a user-supplied manifest both ship a KubeSchedulerConfiguration; a template renders the config twice; merging cluster specs duplicated the additional object.

Related errors


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