kubernetes/kops · error

spotinst: unable to resolve image %q: %v

Error message

spotinst: unable to resolve image %q: %v

What it means

resolveImage resolves an AMI by name/id via cloud.ResolveImage; a resolution failure or nil result is wrapped with the image name. This maps a spec image (e.g. an AMI alias or name) to an actual EC2 Image for the spotinst elastigroup.

Source

Thrown at upup/pkg/fi/cloudup/spotinsttasks/elastigroup.go:1876

	}

	if e.Orientation == nil || (e.Orientation != nil && fi.ValueOf(e.Orientation) == "") {
		e.Orientation = new("balanced")
	}

	if e.Monitoring == nil {
		e.Monitoring = new(false)
	}

	if e.HealthCheckType == nil {
		e.HealthCheckType = new("K8S_NODE")
	}
}

func resolveImage(cloud awsup.AWSCloud, name string) (*ec2types.Image, error) {
	image, err := cloud.ResolveImage(name)
	if err != nil {
		return nil, fmt.Errorf("spotinst: unable to resolve image %q: %v", name, err)
	} else if image == nil {
		return nil, fmt.Errorf("spotinst: unable to resolve image %q: not found", name)
	}

	return image, nil
}

func subnetSlicesEqualIgnoreOrder(l, r []*awstasks.Subnet) bool {
	var lIDs []string
	for _, s := range l {
		lIDs = append(lIDs, *s.ID)
	}

	var rIDs []string
	for _, s := range r {
		if s.ID == nil {
			klog.V(4).Infof("Subnet ID not set; returning not-equal: %v", s)
			return false

View on GitHub (pinned to 4c8573c808)

Solutions

  1. Check the image name/AMI id in the spec; if it's an ami-xxx id, verify it exists in the cluster region (aws ec2 describe-images --image-ids ...).
  2. Remove a pinned ami and let kOps pick the default image for the Kubernetes version and channel (omit the image field).
  3. If the AMI exists but is private, share it with the account or copy it into the target region.
  4. Re-run `kops update cluster` after fixing the image value.

Example fix

// before: AMI from wrong region
image: ami-0abcdef1234567890
// after: let kOps resolve the default image for the channel/k8s version
# remove the image field, or use a valid alias:
image: ubuntu-22.04-amd64
Defensive patterns

Strategy: validation

Validate before calling

// resolve the image up front and fail with a clear message
img, err := cloud.ResolveImage(name)
if err != nil {
    return fmt.Errorf("image %q unresolvable: %v — omit `image` to use the kOps default", name, err)
}
if img == nil {
    return fmt.Errorf("image %q not found in region %s — pick a region-valid alias or AMI", name, region)
}

Try / catch

image, err := resolveImage(cloud, name)
if err != nil {
    if strings.Contains(err.Error(), "not found") {
        // fall back to the default image for the k8s version
        return defaultImageFor(kubernetesVersion, arch)
    }
    return err
}

Prevention

When it happens

Trigger: During Elastigroup rendering, resolveImage(cloud, name) is called with the configured image; ResolveImage returns an error (bad AMI id format, describe-images API failure) or returns nil (no matching image in the region).

Common situations: Hardcoded AMI from another region; deprecated/EOL kOps AMI removed from the region; typo'd image alias; AMI made private or deregistered; using a Debian/Ubuntu name that doesn't exist for the region.

Related errors


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