kubernetes/kops · error
failed to parse spec.template.spec from Deployment: %v
Error message
failed to parse spec.template.spec from Deployment: %v
What it means
In addServiceAccountRole, each apps/v1 Deployment/DaemonSet's spec.template.spec is reparsed into a corev1.PodSpec so the IAM service-account role can be injected. If the YAML at that path cannot be decoded into a PodSpec (missing/invalid fields, wrong types), the function returns this error with the decode reason.
Source
Thrown at pkg/model/components/addonmanifests/remap.go:94
manifest = remapped
}
return manifest, nil
}
func addServiceAccountRole(context *model.KopsModelContext, objects kubemanifest.ObjectList, serviceAccounts map[types.NamespacedName]iam.Subject) error {
if !context.UseServiceAccountExternalPermissions() {
return nil
}
for _, object := range objects {
if !hasPodSpecTemplate(object) {
continue
}
podSpec := &corev1.PodSpec{}
if err := object.Reparse(podSpec, "spec", "template", "spec"); err != nil {
return fmt.Errorf("failed to parse spec.template.spec from Deployment: %v", err)
}
sa := types.NamespacedName{
Name: podSpec.ServiceAccountName,
Namespace: object.GetNamespace(),
}
subject := serviceAccounts[sa]
if subject == nil {
continue
}
if err := iam.AddServiceAccountRole(&context.IAMModelContext, podSpec, subject); err != nil {
return err
}
if err := object.Set(podSpec, "spec", "template", "spec"); err != nil {
return fmt.Errorf("failed to set object: %w", err)
}
View on GitHub (pinned to 4c8573c808)
Solutions
- Fix the PodSpec YAML at spec.template.spec so it is a valid corev1.PodSpec
- Restore the stock addon manifest for the kops version in use
- Remove non-standard/unknown fields from the pod template
- Validate the manifest with kubectl apply --dry-run=server before feeding it to kops
Example fix
# before (type error: containers not a list)
spec:
template:
spec:
containers: dns-controller
# after
spec:
template:
spec:
containers:
- name: dns-controller
image: ... Defensive patterns
Strategy: validation
Validate before calling
// Validate the pod template decodes cleanly before calling kops:
var podSpec corev1.PodSpec
if err := yaml.UnmarshalStrict(templateBytes, &podSpec); err != nil {
return fmt.Errorf("spec.template.spec is not a valid PodSpec: %v", err)
} Type guard
func hasValidPodTemplate(obj *kubemanifest.Object) bool {
var podSpec corev1.PodSpec
return hasPodSpecTemplate(obj) && obj.Reparse(&podSpec, "spec", "template", "spec") == nil
} Try / catch
if err := addServiceAccountRole(ctx, objects, sas); err != nil {
if strings.Contains(err.Error(), "failed to parse spec.template.spec") {
return fmt.Errorf("manifest pod template invalid; restore stock manifest: %w", err)
}
return err
} Prevention
- Run kubectl apply --dry-run=server on custom manifests before kops consumes them
- Avoid unknown/non-standard fields in pod templates
- Keep addon manifests in sync with the kops release channel
When it happens
Trigger: addServiceAccountRole iterating objects where object.Reparse(podSpec, "spec","template","spec") fails: pod template absent, wrong apiVersion/kind slipped past hasPodSpecTemplate is impossible — so realistically invalid or non-standard PodSpec content in an apps/v1 Deployment/DaemonSet.
Common situations: Hand-edited addon manifests with type mismatches (e.g. containers as a string, resources mis-indented); manifests from a newer Kubernetes API with fields the vendored corev1 types reject (strict decoding); YAML indentation errors.
Understand the failure class
- Parsing and encoding errors: unexpected token, malformed input — why parsers reject input and how to find the real culprit.
Related errors
- failed to set object: %w
- expected exactly one container in dns-controller Deployment,
- failed to annotate %q: %w
- failed to add service account for %q: %w
- error remapping manifest %s: %v
AI-assisted analysis of kubernetes/kops@4c8573c808 (2026-09-05).
Data as JSON: /api/errors/e780f3e5b2a72cc4.
Report an issue: GitHub.