kubernetes/kops · error

error marshaling pod to yaml: %v

Error message

error marshaling pod to yaml: %v

What it means

nodeup's KubeControllerManagerBuilder.Build renders the static pod manifest for kube-controller-manager. After building the pod spec it serializes it with k8scodecs.ToVersionedYaml; if that conversion to versioned YAML fails, the underlying codec error is wrapped as 'error marshaling pod to yaml'. This indicates the in-memory pod object could not be converted to a versioned YAML representation.

Source

Thrown at nodeup/pkg/model/kube_controller_manager.go:81

	if err := b.BuildPrivateKeyTask(c, "service-account", pathSrvKCM, "service-account", nil, nil); err != nil {
		return err
	}
	kcm.ServiceAccountPrivateKeyFile = filepath.Join(pathSrvKCM, "service-account.key")

	if err := b.writeServerCertificate(c, &kcm); err != nil {
		return err
	}

	{
		pod, err := b.buildPod(&kcm)
		if err != nil {
			return fmt.Errorf("error building kube-controller-manager pod: %v", err)
		}

		manifest, err := k8scodecs.ToVersionedYaml(pod)
		if err != nil {
			return fmt.Errorf("error marshaling pod to yaml: %v", err)
		}

		c.AddTask(&nodetasks.File{
			Path:     "/etc/kubernetes/manifests/kube-controller-manager.manifest",
			Contents: fi.NewBytesResource(manifest),
			Type:     nodetasks.FileType_File,
		})
	}

	{
		c.AddTask(&nodetasks.File{
			Path:        "/var/log/kube-controller-manager.log",
			Contents:    fi.NewStringResource(""),
			Type:        nodetasks.FileType_File,
			Mode:        s("0400"),
			IfNotExists: true,
		})
	}

View on GitHub (pinned to 4c8573c808)

Solutions

  1. Check the wrapped %v detail in the error message to identify which pod field failed conversion
  2. Verify the kops binary and nodeup version match the cluster spec version (run kops upgrade / use matching release)
  3. Validate the cluster spec (kops validate / inspect KubeControllerManagerConfig values) for invalid or unsupported fields
  4. If reproducible, file an issue with the kops project including the wrapped error text; this is rarely caused by user config alone

Example fix

// before (nodeup binary older than cluster spec)
kops update cluster --yes   # with mismatched kops/nodeup versions
// after
make kops && make nodeup    # rebuild both from the same source
kops update cluster --yes
Defensive patterns

Strategy: try-catch

Validate before calling

if pod == nil || pod.Spec.Containers == nil {
    return fmt.Errorf("kube-controller-manager pod incomplete before marshal")
}
if _, err := json.Marshal(pod); err != nil {
    return fmt.Errorf("pod not serializable: %v", err)
}

Type guard

func isMarshalErr(err error) bool {
    return err != nil && strings.Contains(err.Error(), "error marshaling pod to yaml")
}

Try / catch

manifest, err := k8scodecs.ToVersionedYaml(pod)
if err != nil {
    return fmt.Errorf("error marshaling pod to yaml: %v", err)
}
// caller:
if err := b.Build(c, ...); err != nil {
    if isMarshalErr(err) { /* log pod spec, fix config or version skew */ }
    return err
}

Prevention

When it happens

Trigger: k8scodecs.ToVersionedYaml(pod) returns an error, typically because the pod object contains fields that cannot be converted to the target API version (invalid/unknown fields, nil objects in required positions, or a bad conversion scheme in the codecs setup).

Common situations: kops/nodeup version mismatch where the KubeControllerManagerConfig produced fields not representable in the target manifest API version; corrupt cluster spec values injected into the pod; bugs in the codec scheme initialization; custom builds with modified pod structures.

Related errors


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