{"record":{"id":"aa0d374a41a0114c","repo":"kubernetes/kops","slug":"the-image-for-the-hook-exec-action-not-set","errorCode":null,"errorMessage":"the image for the hook exec action not set","messagePattern":"the image for the hook exec action not set","errorType":"validation","errorClass":null,"httpStatus":null,"severity":"error","filePath":"nodeup/pkg/model/hooks.go","lineNumber":184,"sourceCode":"\n\tcontainerdRunCommand := systemd.EscapeCommand(containerdArgs)\n\tcontainerdPullCommand := systemd.EscapeCommand([]string{\"/usr/bin/ctr\", \"--namespace\", \"k8s.io\", \"image\", \"pull\", containerdImage})\n\n\tunit.Set(\"Unit\", \"Requires\", \"containerd.service\")\n\tunit.Set(\"Service\", \"ExecStartPre\", containerdPullCommand)\n\tunit.Set(\"Service\", \"ExecStart\", containerdRunCommand)\n\tunit.Set(\"Service\", \"Type\", \"oneshot\")\n\tunit.Set(\"Install\", \"WantedBy\", \"multi-user.target\")\n\n\treturn nil\n}\n\n// isValidExecContainerAction checks the validity of the execContainer - personally i think this validation\n// should be done high up the chain, but\nfunc isValidExecContainerAction(action *kops.ExecContainerAction) error {\n\taction.Image = strings.TrimSpace(action.Image)\n\tif action.Image == \"\" {\n\t\treturn errors.New(\"the image for the hook exec action not set\")\n\t}\n\n\treturn nil\n}\n","sourceCodeStart":166,"sourceCodeEnd":189,"githubUrl":"https://github.com/kubernetes/kops/blob/4c8573c808a73d578c5eadc86d410646ea0b0d73/nodeup/pkg/model/hooks.go#L166-L189","documentation":"Wraps a failure from the autoscaling DetachInstances API in AWSCloud.DetachInstance. After successfully tagging the instance, kOps asks the ASG to detach the instance without decrementing desired capacity. If the AWS call fails, the SDK error is wrapped here.","triggerScenarios":"DetachInstances call fails because the ASG no longer exists, the instance was already detached or terminated, the instance ID is not in the ASG, or throttling/credentials issues.","commonSituations":"Concurrent rolling updates double-detaching the same node; ASG deleted manually while kops still tracks it; instance already replaced by the ASG; transient AWS throttling.","solutions":["Check the ASG still exists and contains the instance in the AWS console/CLI","Retry the rolling update — detach is idempotent-safe when the instance is gone","Verify IAM permissions for autoscaling:DetachInstances","Refresh cloud state with `kops rolling-update cluster --cloudonly` or re-list groups"],"exampleFix":null,"handlingStrategy":"retry","validationCode":"out, err := cloud.Autoscaling().DescribeAutoScalingGroups(ctx, &autoscaling.DescribeAutoScalingGroupsInput{AutoScalingGroupNames: []string{asgName}})\nif err != nil || len(out.AutoScalingGroups) == 0 { return fmt.Errorf(\"ASG %q unavailable for detach\", asgName) }","typeGuard":null,"tryCatchPattern":"err := cloud.DetachInstance(ctx, instance)\nif err != nil && strings.Contains(err.Error(), \"error detaching instance\") {\n  // check whether the instance already left the ASG; treat AlreadyDetached/Terminated as success\n  if asgHasInstance(ctx, cloud, asgName, id) { retryDetach() } else { logAlreadyDetached() }\n}","preventionTips":["Run only one rolling update at a time per cluster","Do not manually delete ASGs while kops manages them","Grant autoscaling:DetachInstances in the IAM policy","Retry transient AWS errors before failing the whole upgrade"],"tags":["aws","autoscaling","detach"],"backgroundTag":"aws-api-error-wrapped","analyzedSha":"4c8573c808a73d578c5eadc86d410646ea0b0d73","analyzedAt":"2026-09-05T04:13:19.212Z","contentChangedAt":"2026-09-05T04:13:19.212Z","schemaVersion":2},"datasetVersion":"2026-09-12T07:17:12.445Z"}