kubernetes/kops · error

error setting clientConnection.kubeconfig in kube-scheduler

Error message

error setting clientConnection.kubeconfig in kube-scheduler configuration: %w

What it means

After selecting (or defaulting) the KubeSchedulerConfiguration, buildSchedulerConfig sets clientConnection.kubeconfig to the well-known kube-scheduler kubeconfig path via unstructured.SetNestedField. This fails only if the intermediate structure is wrong (e.g. clientConnection exists but is not a map, or the object shape is unexpected), so the wrapped error reports why the nested field could not be set.

Source

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

	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)
	}

	kubeScheduler := b.Cluster.Spec.KubeScheduler
	if kubeScheduler != nil {
		if err := MapToUnstructured(kubeScheduler, config); err != nil {
			return nil, err
		}
	}

	configYAML, err := yaml.Marshal(config)
	if err != nil {
		return nil, err
	}
	return configYAML, nil
}

// MapToUnstructured reflects the options interface and extracts the parameters for the config file
func MapToUnstructured(options interface{}, target *unstructured.Unstructured) error {

View on GitHub (pinned to 4c8573c808)

Solutions

  1. Inspect the KubeSchedulerConfiguration object and ensure clientConnection is a nested object (map), not a scalar
  2. Let the builder create the default config by removing the malformed AdditionalObject
  3. Validate the manifest with a schema tool (kubectl apply --dry-run=server) before adding it as an AdditionalObject

Example fix

# before
clientConnection: /etc/kubernetes/kubeconfig
# after
clientConnection:
  kubeconfig: /etc/kubernetes/kubeconfig
Defensive patterns

Strategy: validation

Validate before calling

cc, found, err := unstructured.NestedFieldNoCopy(config.Object, "clientConnection")
if found {
    if _, ok := cc.(map[string]interface{}); !ok {
        return fmt.Errorf("clientConnection must be an object, got %T", cc)
    }
}

Type guard

func isNestedMap(v interface{}) bool {
    _, ok := v.(map[string]interface{})
    return ok
}

Try / catch

if _, err := buildSchedulerConfig(b); err != nil {
    if strings.Contains(err.Error(), "error setting clientConnection.kubeconfig") {
        // drop/repair the offending KubeSchedulerConfiguration and retry with defaults
    }
    return err
}

Prevention

When it happens

Trigger: Calling Build → buildSchedulerConfig with a KubeSchedulerConfiguration AdditionalObject whose clientConnection field is not an object/map (e.g. a string or null leaf) so unstructured.SetNestedField cannot walk/create the path.

Common situations: A hand-written scheduler config YAML where clientConnection was mistyped as a scalar; a rendered template producing a malformed nested field; older config versions with a different schema.

Understand the failure class

Background: Schema validation failed / invalid input schema: payload rejected because its shape doesn't match the expected schema — this error's family across 28 libraries.

Related errors


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