{"record":{"id":"b88e02948bb873a5","repo":"kubernetes/kops","slug":"error-detaching-instance-q-v","errorCode":null,"errorMessage":"error detaching instance %q: %v","messagePattern":"error detaching instance %q: (.+?)","errorType":"exception","errorClass":null,"httpStatus":null,"severity":"error","filePath":"pkg/instancegroups/instancegroups.go","lineNumber":640,"sourceCode":"\n// detachInstance detaches a Cloud Instance\nfunc (c *RollingUpdateCluster) detachInstance(u *cloudinstances.CloudInstance) error {\n\tid := u.ID\n\tnodeName := \"\"\n\tif u.Node != nil {\n\t\tnodeName = u.Node.Name\n\t}\n\tif nodeName != \"\" {\n\t\tklog.Infof(\"Detaching instance %q, node %q, in group %q.\", id, nodeName, u.CloudInstanceGroup.HumanName)\n\t} else {\n\t\tklog.Infof(\"Detaching instance %q, in group %q.\", id, u.CloudInstanceGroup.HumanName)\n\t}\n\n\tif err := c.Cloud.DetachInstance(u); err != nil {\n\t\tif nodeName != \"\" {\n\t\t\treturn fmt.Errorf(\"error detaching instance %q, node %q: %v\", id, nodeName, err)\n\t\t}\n\t\treturn fmt.Errorf(\"error detaching instance %q: %v\", id, err)\n\t}\n\n\treturn nil\n}\n\n// deleteInstance deletes an Cloud Instance.\nfunc (c *RollingUpdateCluster) deleteInstance(u *cloudinstances.CloudInstance) error {\n\tid := u.ID\n\tnodeName := \"\"\n\tif u.Node != nil {\n\t\tnodeName = u.Node.Name\n\t}\n\tif nodeName != \"\" {\n\t\tklog.Infof(\"Stopping instance %q, node %q, in group %q (this may take a while).\", id, nodeName, u.CloudInstanceGroup.HumanName)\n\t} else {\n\t\tklog.Infof(\"Stopping instance %q, in group %q (this may take a while).\", id, u.CloudInstanceGroup.HumanName)\n\t}\n","sourceCodeStart":622,"sourceCodeEnd":658,"githubUrl":"https://github.com/kubernetes/kops/blob/4c8573c808a73d578c5eadc86d410646ea0b0d73/pkg/instancegroups/instancegroups.go#L622-L658","documentation":"Same detach failure as its sibling error, but for instances with no associated Kubernetes node (nodeName == \"\"), e.g. control-plane or bastion instances identified only by cloud ID. It wraps the cloud provider DetachInstance error with just the instance ID.","triggerScenarios":"c.Cloud.DetachInstance(u) fails and nodeName == \"\": detach of a control-plane/bastion instance rejected by the cloud API — instance not in group, permission denied, throttling, or instance already terminated.","commonSituations":"Rolling the control-plane of a cluster whose instances were modified out-of-band; IAM misconfiguration; transient cloud API errors during etcd member replacement rolls.","solutions":["Re-run rolling update to refresh group membership","Verify IAM permissions for detaching instances","Check the instance still exists and belongs to the group in the cloud console","Retry after transient cloud API errors"],"exampleFix":null,"handlingStrategy":"try-catch","validationCode":"// verify the instance exists in the cloud provider before detaching\ninst, err := ec2Client.DescribeInstances(&ec2.DescribeInstancesInput{InstanceIds: []*string{&u.ID}})\n// if not found or not in the expected group, refresh group state first","typeGuard":"func detachable(u *cloudinstances.CloudInstance) bool { return u != nil && u.ID != \"\" }","tryCatchPattern":"if err := c.Cloud.DetachInstance(u); err != nil {\n    if isNotFound(err) { return nil } // instance already gone\n    return fmt.Errorf(\"error detaching instance %q: %v\", id, err)\n}","preventionTips":["Refresh group membership before each control-plane roll step","Verify IAM detach permissions for control-plane instance groups","Avoid external automation touching control-plane instances during rolls"],"tags":["cloud","detach","rolling-update"],"backgroundTag":"cloud-instance-detach-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"}