kubernetes/kops · error
unable to resolve image %q: not found
Error message
unable to resolve image %q: not found
What it means
kops successfully queried EC2 for the image but ResolveImage returned nil — no matching AMI exists (or is visible to the account) for the given image spec. karpenterRootDeviceName turns that into 'unable to resolve image %q: not found' while building the Karpenter EC2NodeClass.
Source
Thrown at upup/pkg/fi/cloudup/template_functions_karpenter.go:395
},
}, nil
}
// karpenterRootDeviceName resolves the root device name of the InstanceGroup image, so
// that the generated block device mapping overrides the image's root volume rather than
// attaching an additional one. The name varies between images (/dev/xvda, /dev/sda1),
// so it has to come from the image itself.
func (tf *TemplateFunctions) karpenterRootDeviceName(image string) (string, error) {
cloud, ok := tf.cloud.(awsup.AWSCloud)
if !ok {
return "", fmt.Errorf("expected an AWS cloud, got %T", tf.cloud)
}
resolved, err := cloud.ResolveImage(image)
if err != nil {
return "", fmt.Errorf("unable to resolve image %q: %w", image, err)
}
if resolved == nil {
return "", fmt.Errorf("unable to resolve image %q: not found", image)
}
rootDeviceName := fi.ValueOf(resolved.RootDeviceName)
if rootDeviceName == "" {
return "", fmt.Errorf("image %q has no root device name", image)
}
return rootDeviceName, nil
}
func (tf *TemplateFunctions) buildKarpenterNodePool(ig *kops.InstanceGroup) (*karpenterNodePool, error) {
labels, err := nodelabels.BuildNodeLabels(tf.Cluster, ig)
if err != nil {
return nil, fmt.Errorf("building node labels for %q: %w", ig.Name, err)
}
labels = karpenterNodePoolTemplateLabels(labels)
template := karpenterNodeClaimTemplate{
Spec: karpenterNodeClaimSpec{
Requirements: tf.karpenterRequirements(ig),View on GitHub (pinned to 4c8573c808)
Solutions
- Confirm the AMI id exists via `aws ec2 describe-images --image-ids <id>` in the cluster's region
- Check the region in the cluster spec matches where the AMI lives
- Use a kops-supported image alias or a current AMI (e.g. from kops ensure-defaults or official image lists)
- If the AMI was deleted, pick a new one and update the instance group spec
Example fix
// before image: ami-0deleted1234567890 // after image: ami-0abcdef1234567890 # verified in target region via aws ec2 describe-images
Defensive patterns
Strategy: validation
Validate before calling
// verify AMI exists before update
out, err := ec2Client.DescribeImages(&ec2.DescribeImagesInput{ImageIds: []string{image}})
if err != nil || len(out.Images) == 0 {
return fmt.Errorf("AMI %s not found in region %s", image, region)
} Try / catch
if _, err := tf.karpenterRootDeviceName(image); err != nil && strings.Contains(err.Error(), "not found") {
return fmt.Errorf("AMI missing; pick a current image for region %s", region)
} Prevention
- Confirm AMI ids with `aws ec2 describe-images --image-ids` in the cluster region
- Watch for kops image deprecations and update the cluster spec accordingly
- Avoid hard-coding AMIs from a different region
When it happens
Trigger: Passing an image identifier that matches zero AMIs: deleted/deregistered AMI id, wrong owner alias, or a name filter matching nothing in the configured region.
Common situations: AMI deregistered since the cluster spec was written; AMI exists in us-east-1 but cluster targets eu-west-1; custom owner alias not recognized; typo in the image name.
Related errors
- could not find Image for %q
- image %q has no root device name
- found no ElasticIPs for: %v
- unable to find specified SSH key %q
- image name specification not recognized: %q
AI-assisted analysis of kubernetes/kops@4c8573c808 (2026-09-05).
Data as JSON: /api/errors/8bf3171f91b60761.
Report an issue: GitHub.