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

  1. Fix the PodSpec YAML at spec.template.spec so it is a valid corev1.PodSpec
  2. Restore the stock addon manifest for the kops version in use
  3. Remove non-standard/unknown fields from the pod template
  4. 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

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

Related errors


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