kubernetes/kops · error

NAT EC2 Instance %q not found

Error message

NAT EC2 Instance %q not found

What it means

In Instance.RenderAWS, when the task is creating a new instance (no existing 'actual' state) but the task is marked Shared, kOps expects the instance to already exist and be discoverable by ID. If it was not found during Find, RenderAWS refuses to create a new one and fails with 'NAT EC2 Instance %q not found'. Shared instances are treated as pre-existing external infrastructure (historically NAT instances), so kOps never creates them.

Source

Thrown at upup/pkg/fi/cloudup/awstasks/instance.go:218

func (e *Instance) Run(c *fi.CloudupContext) error {
	return fi.CloudupDefaultDeltaRunMethod(e, c)
}

func (_ *Instance) CheckChanges(a, e, changes *Instance) error {
	if a != nil {
		if !fi.ValueOf(e.Shared) && e.Name == nil {
			return fi.RequiredField("Name")
		}
	}
	return nil
}

func (_ *Instance) RenderAWS(t *awsup.AWSAPITarget, a, e, changes *Instance) error {
	ctx := context.TODO()
	if a == nil {

		if fi.ValueOf(e.Shared) {
			return fmt.Errorf("NAT EC2 Instance %q not found", fi.ValueOf(e.ID))
		}

		if e.ImageID == nil {
			return fi.RequiredField("ImageID")
		}
		image, err := t.Cloud.ResolveImage(fi.ValueOf(e.ImageID))
		if err != nil {
			return err
		}

		klog.V(2).Infof("Creating Instance with Name:%q", fi.ValueOf(e.Name))
		request := &ec2.RunInstancesInput{
			ImageId:      image.ImageId,
			InstanceType: e.InstanceType,
			MinCount:     aws.Int32(1),
			MaxCount:     aws.Int32(1),
		}

View on GitHub (pinned to 4c8573c808)

Solutions

  1. Set the correct instance ID for the shared Instance task in the cluster spec (kops edit cluster) and re-run kops update.
  2. Verify the instance exists: `aws ec2 describe-instances --instance-ids <id>` in the same region/VPC kOps targets.
  3. If kOps should manage the instance, remove Shared:true from the task so it creates the instance.
  4. Re-run discovery: ensure name tags match what Find searches for, or point the task at the right cluster.
  5. If the shared instance is truly gone, restore it (or its snapshot) or un-share the task.

Example fix

// before (cluster spec, instance task)
instance/k8s-cluster-a-nat:
  shared: true
  # id missing -> RenderAWS fails
// after
instance/k8s-cluster-a-nat:
  shared: true
  id: i-0abc123def4567890
Defensive patterns

Strategy: validation

Validate before calling

// Before applying a cluster with a shared instance, verify the ID exists
goVerify := func(instID, region string) error {
	cfg, _ := config.LoadDefaultConfig(ctx, config.WithRegion(region))
	client := ec2.NewFromConfig(cfg)
	out, err := client.DescribeInstances(ctx, &ec2.DescribeInstancesInput{
		InstanceIds: []string{instID},
	})
	if err != nil || len(out.Reservations) == 0 {
		return fmt.Errorf("shared instance %s not found in %s", instID, region)
	}
	return nil
}

Try / catch

err := applyCluster(ctx)
if err != nil && strings.Contains(err.Error(), "not found") && strings.Contains(err.Error(), "NAT EC2 Instance") {
	// shared instance missing: prompt to fix the ID or un-share the task
	return fmt.Errorf("shared instance referenced in spec does not exist; set a valid id or remove shared:true: %w", err)
}
return err

Prevention

When it happens

Trigger: Rendering an Instance task with Shared=true where a==nil (Find returned no matching instance), e.g. the ID is unset, points to a deleted/terminated instance, or Find could not match by name/tags in the target region/VPC.

Common situations: Config marks a NAT/bastion instance as shared but the instance ID is missing from the cluster spec; the referenced instance was terminated or lives in another region/account; typo'd or stale ID after cluster import; running kops against a different VPC than where the shared instance exists.

Related errors


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