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
- Check the wrapped %v detail in the error message to identify which pod field failed conversion
- Verify the kops binary and nodeup version match the cluster spec version (run kops upgrade / use matching release)
- Validate the cluster spec (kops validate / inspect KubeControllerManagerConfig values) for invalid or unsupported fields
- 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
- Keep kops and nodeup binaries on the exact same version
- Never hand-edit generated NodeupConfig or pod templates
- Validate the cluster spec after every kops upgrade before updating nodes
- Log the full wrapped error text to identify the failing field
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
- error marshaling manifest to yaml: %v
- error building kube-controller-manager flags: %v
- error building kube-proxy manifest: %v
- KubeProxy not configured
- error marshaling pod to yaml: %v
AI-assisted analysis of kubernetes/kops@4c8573c808 (2026-09-05).
Data as JSON: /api/errors/c39f84788f265198.
Report an issue: GitHub.