{"record":{"id":"27d7b476ec2654f5","repo":"kubernetes/kops","slug":"unable-to-find-iam-profile-link-for-instance-group","errorCode":null,"errorMessage":"unable to find IAM profile link for instance group %q: %w","messagePattern":"unable to find IAM profile link for instance group %q: %w","errorType":"exception","errorClass":null,"httpStatus":null,"severity":"error","filePath":"pkg/model/awsmodel/autoscalinggroup.go","lineNumber":167,"sourceCode":"\t\t\t\tHeartbeatTimeout:    heartbeatTimeout,\n\t\t\t\tLifecycleTransition: aws.String(\"autoscaling:EC2_INSTANCE_LAUNCHING\"),\n\t\t\t\tEnabled:             &enableHook,\n\t\t\t}\n\n\t\t\tc.AddTask(lifecyleTask)\n\n\t\t}\n\t}\n\n\treturn nil\n}\n\n// buildLaunchTemplateTask is responsible for creating the template task into the aws model\nfunc (b *AutoscalingGroupModelBuilder) buildLaunchTemplateTask(c *fi.CloudupModelBuilderContext, name string, ig *kops.InstanceGroup, userData fi.Resource) (*awstasks.LaunchTemplate, error) {\n\t// @step: add the iam instance profile\n\tlink, err := b.LinkToIAMInstanceProfile(ig)\n\tif err != nil {\n\t\treturn nil, fmt.Errorf(\"unable to find IAM profile link for instance group %q: %w\", ig.ObjectMeta.Name, err)\n\t}\n\n\trootVolumeSize, err := defaults.DefaultInstanceGroupVolumeSize(ig.Spec.Role)\n\tif err != nil {\n\t\treturn nil, err\n\t}\n\tvar rootVolumeType ec2types.VolumeType\n\trootVolumeEncryption := DefaultVolumeEncryption\n\trootVolumeKmsKey := \"\"\n\n\tif ig.Spec.RootVolume != nil {\n\t\tif fi.ValueOf(ig.Spec.RootVolume.Size) > 0 {\n\t\t\trootVolumeSize = fi.ValueOf(ig.Spec.RootVolume.Size)\n\t\t}\n\n\t\trootVolumeType = ec2types.VolumeType(fi.ValueOf(ig.Spec.RootVolume.Type))\n\n\t\tif ig.Spec.RootVolume.Encryption != nil {","sourceCodeStart":149,"sourceCodeEnd":185,"githubUrl":"https://github.com/kubernetes/kops/blob/4c8573c808a73d578c5eadc86d410646ea0b0d73/pkg/model/awsmodel/autoscalinggroup.go#L149-L185","documentation":"buildLaunchTemplateTask calls LinkToIAMInstanceProfile to resolve the IAM instance profile task for the instance group; when that lookup fails (typically the IAM profile builder produced no matching task or the name lookup errored), the error is wrapped with the instance-group name and aborts the launch-template build.","triggerScenarios":"`kops update cluster` when the IAM instance profile for the instance group cannot be linked — e.g. the IAM builder did not create the profile task for the group's role, an IAM name/permission conflict caused the IAM task build to fail upstream, or a custom/external IAM profile reference is unresolvable.","commonSituations":"Clusters with useInstanceProfilesForDNS or custom IAM settings where the profile name collides or exceeds AWS's 64-char profile name limit; running with --iam=false after previously enabling IAM so no profile task exists; permission denied reading existing IAM roles/profiles in the AWS account.","solutions":["Inspect the wrapped inner error (%w) printed by kops — it names the underlying cause (e.g. name too long, permission denied) and fix that first.","Ensure the cluster spec has IAM enabled (no --iam=false) so the IAM instance profile task is generated for the instance group's role.","If using a custom IAM profile name, shorten it: AWS instance profile names are limited to 64 characters; adjust spec role naming or the cluster name.","Verify AWS credentials/permissions (iam:GetInstanceProfile, iam:ListRoles) so the existing profile can be resolved.","Re-run `kops update cluster --target=terraform` or dry-run to confirm the IAM tasks are built before the ASG model."],"exampleFix":"// before\nkops update cluster mycluster --iam=false\n// after\nkops update cluster mycluster  # let kOps build the IAM instance profile task","handlingStrategy":"validation","validationCode":"# preflight: ensure IAM is enabled and profile name within AWS limits\nname_len=$((${#CLUSTER_NAME} + ${#IG_NAME} + 20))\n[ $name_len -le 64 ] || { echo \"IAM instance profile name would exceed 64 chars\"; exit 1; }\nkops get cluster -oyaml | grep -q 'iam:' && echo \"iam configured\" || echo \"warning: no iam block\"","typeGuard":null,"tryCatchPattern":"// kops is a CLI: capture and inspect the wrapped cause\nif out, err := exec.Command(\"kops\", \"update\", \"cluster\", cluster).CombinedOutput(); err != nil {\n  if strings.Contains(string(out), \"unable to find IAM profile link\") {\n    // inspect inner %w cause, fix IAM spec/permissions, then retry\n  }\n}","preventionTips":["Do not run with --iam=false on clusters that need kOps-managed instance profiles","Keep cluster + instance-group names short so generated IAM profile names stay under 64 chars","Verify AWS IAM read permissions (iam:GetInstanceProfile, iam:ListRoles) before running update","Check the full wrapped error chain for the real root cause before changing config"],"tags":["aws","iam","instance-group","model-building"],"backgroundTag":"missing-iam-instance-profile","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"}