kubernetes/kops · error
unable to resolve image %q: %w
Error message
unable to resolve image %q: %w
What it means
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.
Source
Thrown at upup/pkg/fi/cloudup/template_functions_karpenter.go:392
DeviceName: rootDeviceName,
EBS: ebs,
RootVolume: new(true),
},
}, 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)
View on GitHub (pinned to 4c8573c808)
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
Example fix
// before image: ami-nonexistent // after image: ami-0abcdef1234567890 # or a valid alias like 099720109477/ubuntu-jammy-22.04-amd64-server-*
Defensive patterns
Strategy: try-catch
Validate before calling
// pre-check the image resolves before rendering templates
cloud := tf.cloud.(awsup.AWSCloud)
if _, err := cloud.ResolveImage(image); err != nil {
return fmt.Errorf("image %q cannot be resolved: %w", image, err)
} Try / catch
if _, err := tf.karpenterRootDeviceName(image); err != nil {
var resolveErr *fmt.WrapError
if strings.Contains(err.Error(), "unable to resolve image") {
// inspect wrapped cause: API/network/credential issue
return fmt.Errorf("check AWS API access and image spec: %w", err)
}
return err
} Prevention
- 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)
When it happens
Trigger: 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.
Common situations: 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.
Related errors
- unable to resolve image %q: not found
- image %q has no root device name
- DIGITALOCEAN_ACCESS_TOKEN is required
- timed out waiting for volume to detach
- unexpected number of network interfaces for instance %q: %v
AI-assisted analysis of kubernetes/kops@4c8573c808 (2026-09-05).
Data as JSON: /api/errors/530be7de17c7699e.
Report an issue: GitHub.