{"record":{"id":"530be7de17c7699e","repo":"kubernetes/kops","slug":"unable-to-resolve-image-q-w","errorCode":null,"errorMessage":"unable to resolve image %q: %w","messagePattern":"unable to resolve image %q: %w","errorType":"exception","errorClass":null,"httpStatus":null,"severity":"error","filePath":"upup/pkg/fi/cloudup/template_functions_karpenter.go","lineNumber":392,"sourceCode":"\t\t\tDeviceName: rootDeviceName,\n\t\t\tEBS:        ebs,\n\t\t\tRootVolume: new(true),\n\t\t},\n\t}, nil\n}\n\n// karpenterRootDeviceName resolves the root device name of the InstanceGroup image, so\n// that the generated block device mapping overrides the image's root volume rather than\n// attaching an additional one. The name varies between images (/dev/xvda, /dev/sda1),\n// so it has to come from the image itself.\nfunc (tf *TemplateFunctions) karpenterRootDeviceName(image string) (string, error) {\n\tcloud, ok := tf.cloud.(awsup.AWSCloud)\n\tif !ok {\n\t\treturn \"\", fmt.Errorf(\"expected an AWS cloud, got %T\", tf.cloud)\n\t}\n\tresolved, err := cloud.ResolveImage(image)\n\tif err != nil {\n\t\treturn \"\", fmt.Errorf(\"unable to resolve image %q: %w\", image, err)\n\t}\n\tif resolved == nil {\n\t\treturn \"\", fmt.Errorf(\"unable to resolve image %q: not found\", image)\n\t}\n\trootDeviceName := fi.ValueOf(resolved.RootDeviceName)\n\tif rootDeviceName == \"\" {\n\t\treturn \"\", fmt.Errorf(\"image %q has no root device name\", image)\n\t}\n\treturn rootDeviceName, nil\n}\n\nfunc (tf *TemplateFunctions) buildKarpenterNodePool(ig *kops.InstanceGroup) (*karpenterNodePool, error) {\n\tlabels, err := nodelabels.BuildNodeLabels(tf.Cluster, ig)\n\tif err != nil {\n\t\treturn nil, fmt.Errorf(\"building node labels for %q: %w\", ig.Name, err)\n\t}\n\tlabels = karpenterNodePoolTemplateLabels(labels)\n","sourceCodeStart":374,"sourceCodeEnd":410,"githubUrl":"https://github.com/kubernetes/kops/blob/4c8573c808a73d578c5eadc86d410646ea0b0d73/upup/pkg/fi/cloudup/template_functions_karpenter.go#L374-L410","documentation":"After asserting the cloud is AWSCloud, karpenterRootDeviceName calls cloud.ResolveImage(image) to look up the AMI. When that AWS API lookup itself fails (network error, invalid image format, API error), the failure is wrapped with this message and returned.","triggerScenarios":"cloud.ResolveImage returns an error for the given image string — e.g. malformed AMI name, AWS EC2 DescribeImages API error, throttling, or connectivity failure during template rendering for a Karpenter EC2NodeClass.","commonSituations":"Typo'd AMI name/alias in the instance group spec; AWS API outage or rate limiting during `kops update cluster`; credentials lacking ec2:DescribeImages permission; specifying an image in a region where it does not exist.","solutions":["Verify the image string is a valid AMI id, alias (owner/name), or name resolvable in the target region","Check AWS credentials and that ec2:DescribeImages is allowed","Retry kops update cluster if the failure was transient (API throttling/network)","Inspect the wrapped inner error (%w) for the root cause"],"exampleFix":"// before\nimage: ami-nonexistent\n// after\nimage: ami-0abcdef1234567890  # or a valid alias like 099720109477/ubuntu-jammy-22.04-amd64-server-*","handlingStrategy":"try-catch","validationCode":"// pre-check the image resolves before rendering templates\ncloud := tf.cloud.(awsup.AWSCloud)\nif _, err := cloud.ResolveImage(image); err != nil {\n\treturn fmt.Errorf(\"image %q cannot be resolved: %w\", image, err)\n}","typeGuard":null,"tryCatchPattern":"if _, err := tf.karpenterRootDeviceName(image); err != nil {\n\tvar resolveErr *fmt.WrapError\n\tif strings.Contains(err.Error(), \"unable to resolve image\") {\n\t\t// inspect wrapped cause: API/network/credential issue\n\t\treturn fmt.Errorf(\"check AWS API access and image spec: %w\", err)\n\t}\n\treturn err\n}","preventionTips":["Verify ec2:DescribeImages IAM permission before running kops update","Pin valid AMI ids/aliases for the target region","Retry on transient AWS API errors (throttling)"],"tags":["aws","ec2","image-resolution","karpenter"],"backgroundTag":"image-resolution-failed","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"}