kubernetes/kops · error

unable to resolve image: %q: %v

Error message

unable to resolve image: %q: %v

What it means

buildRootDevice resolves the AMI for a launch template's root block device mapping via cloud.ResolveImage(image). If ResolveImage returns an error (AWS DescribeImages failure, multiple/ambiguous matches, invalid image spec), the error is wrapped with the image name. This is distinct from the 'not found' variant: here the lookup itself failed.

Source

Thrown at upup/pkg/fi/cloudup/awstasks/launchtemplate.go:116

	_ fi.CloudupDeletion          = &deleteLaunchTemplate{}
)

// CompareWithID implements the comparable interface
func (t *LaunchTemplate) CompareWithID() *string {
	return t.ID
}

// buildRootDevice is responsible for retrieving a boot device mapping from the image name
func (t *LaunchTemplate) buildRootDevice(cloud awsup.AWSCloud) (map[string]*BlockDeviceMapping, error) {
	image := fi.ValueOf(t.ImageID)
	if image == "" {
		return map[string]*BlockDeviceMapping{}, nil
	}

	// @step: resolve the image ami
	img, err := cloud.ResolveImage(image)
	if err != nil {
		return nil, fmt.Errorf("unable to resolve image: %q: %v", image, err)
	} else if img == nil {
		return nil, fmt.Errorf("unable to resolve image: %q: not found", image)
	}

	b := &BlockDeviceMapping{
		EbsDeleteOnTermination: aws.Bool(true),
		EbsVolumeSize:          t.RootVolumeSize,
		EbsVolumeType:          t.RootVolumeType,
		EbsVolumeIops:          t.RootVolumeIops,
		EbsVolumeThroughput:    t.RootVolumeThroughput,
		EbsEncrypted:           t.RootVolumeEncryption,
	}
	if aws.ToBool(t.RootVolumeEncryption) && aws.ToString(t.RootVolumeKmsKey) != "" {
		b.EbsKmsKey = t.RootVolumeKmsKey
	}

	bm := map[string]*BlockDeviceMapping{
		aws.ToString(img.RootDeviceName): b,

View on GitHub (pinned to 4c8573c808)

Solutions

  1. Read the wrapped error: if ambiguous, pin the image to a specific AMI ID or add an owner filter.
  2. Verify the image value in the InstanceGroup (kops get ig --name -o yaml) is a valid AMI id (ami-...) or supported alias.
  3. Retry if the underlying error was throttling/transient.
  4. Confirm the AMI exists in the cluster's region.

Example fix

// before (InstanceGroup)
image: 099720109477/ubuntu-jammy-22.04  // ambiguous
// after
image: ami-0abcdef1234567890
Defensive patterns

Strategy: validation

Validate before calling

// verify the image resolves before apply
aws ec2 describe-images --region $REGION --image-ids $IMAGE
// or for names: aws ec2 describe-images --filters Name=name,Values=$IMAGE_NAME Name=owner-alias,Values=amazon

Type guard

func isAMIID(image string) bool { return regexp.MustCompile(`^ami-[0-9a-f]{8,17}$`).MatchString(image) }

Try / catch

if err != nil && strings.Contains(err.Error(), "unable to resolve image") { check wrapped cause; pin a specific AMI ID and retry }

Prevention

When it happens

Trigger: RenderAWS or RenderTerraform calls buildRootDevice; cloud.ResolveImage(image) returns non-nil error - e.g. DescribeImages API error, ambiguous image query returning multiple results, or an unparseable image identifier.

Common situations: Image alias/name matching multiple AMIs after owner published new images; AWS API error/throttling during DescribeImages; malformed ami string in the InstanceGroup's image field; region where the AMI is not available.

Related errors


AI-assisted analysis of kubernetes/kops@4c8573c808 (2026-09-05). Data as JSON: /api/errors/1df912ce9b17e335. Report an issue: GitHub.