{"record":{"id":"f06d7e309402ee53","repo":"kubernetes/kops","slug":"failed-to-parse-spec-template-spec-from-deployment","errorCode":null,"errorMessage":"failed to parse spec.template.spec from Deployment: %v","messagePattern":"failed to parse spec\\.template\\.spec from Deployment: (.+?)","errorType":"exception","errorClass":null,"httpStatus":null,"severity":"error","filePath":"pkg/model/components/addonmanifests/dnscontroller/remap.go","lineNumber":52,"sourceCode":"\n\tvar deployments []*kubemanifest.Object\n\tfor _, object := range objects {\n\t\tif object.Kind() != \"Deployment\" {\n\t\t\tcontinue\n\t\t}\n\t\tif object.APIVersion() != \"apps/v1\" {\n\t\t\tcontinue\n\t\t}\n\t\tdeployments = append(deployments, object)\n\t}\n\n\tif len(deployments) != 1 {\n\t\treturn fmt.Errorf(\"expected exactly one Deployment in dns-controller manifest, found %d\", len(deployments))\n\t}\n\n\tpodSpec := &corev1.PodSpec{}\n\tif err := deployments[0].Reparse(podSpec, \"spec\", \"template\", \"spec\"); err != nil {\n\t\treturn fmt.Errorf(\"failed to parse spec.template.spec from Deployment: %v\", err)\n\t}\n\n\tcontainers := podSpec.Containers\n\tif len(containers) != 1 {\n\t\treturn fmt.Errorf(\"expected exactly one container in dns-controller Deployment, found %d\", len(containers))\n\t}\n\n\tif err := iam.AddServiceAccountRole(&context.IAMModelContext, podSpec, &ServiceAccount{}); err != nil {\n\t\treturn err\n\t}\n\n\tif err := deployments[0].Set(podSpec, \"spec\", \"template\", \"spec\"); err != nil {\n\t\treturn err\n\t}\n\n\treturn nil\n}\n","sourceCodeStart":34,"sourceCodeEnd":70,"githubUrl":"https://github.com/kubernetes/kops/blob/4c8573c808a73d578c5eadc86d410646ea0b0d73/pkg/model/components/addonmanifests/dnscontroller/remap.go#L34-L70","documentation":"After confirming exactly one Deployment, Remap reparses the nested spec.template.spec into a corev1.PodSpec via the flexible reparser. If the manifest's Deployment lacks that path or its YAML cannot be decoded into a PodSpec, Reparse errors and this wrapped error is returned.","triggerScenarios":"A dns-controller manifest Deployment whose template pod spec is missing, renamed, or structurally invalid when running `kops update cluster` remapping of addon images.","commonSituations":"Hand-edited manifests with modified podSpec fields; addon manifests from incompatible kops versions; malformed YAML indentation under spec.template.spec.","solutions":["Restore the original bundled dns-controller manifest so spec.template.spec matches the expected corev1.PodSpec schema.","Validate the Deployment YAML structure (spec.template.spec.containers present) before updating the cluster.","Upgrade/downgrade kops to the version matching the addon manifest bundle."],"exampleFix":"// before (invalid manifest)\nspec:\n  template: {}\n// after\nspec:\n  template:\n    spec:\n      containers:\n      - name: dns-controller\n        ...","handlingStrategy":"type-guard","validationCode":"var deploy appsv1.Deployment\nif err := yaml.Unmarshal(manifestSection, &deploy); err != nil {\n  return err\n}\nif deploy.Spec.Template.Spec.Containers == nil {\n  return fmt.Errorf(\"deployment %q lacks spec.template.spec.containers\", deploy.Name)\n}","typeGuard":"func hasPodSpec(d *appsv1.Deployment) bool {\n  return d.Spec.Template.Spec.Containers != nil\n}","tryCatchPattern":null,"preventionTips":["Keep spec.template.spec intact when editing addon manifests.","Lint manifests against the corev1.PodSpec schema.","Restore stock manifests after failed manual edits."],"tags":["addons","dns-controller","manifest","parsing"],"backgroundTag":"addon-manifest-parse-failed","analyzedSha":"4c8573c808a73d578c5eadc86d410646ea0b0d73","analyzedAt":"2026-09-05T04:13:19.212Z","contentChangedAt":"2026-09-05T04:13:19.212Z","schemaVersion":2},"datasetVersion":"2026-09-12T12:17:11.808Z"}