kubernetes/kops · error

NAT gateway %q not found

Error message

NAT gateway %q not found

What it means

During RenderAWS, when the NatGateway task is new (a == nil) but e.Shared is true, kOps expects the gateway to already exist under a user-supplied ID. If no ID is set (or lookup produced none), it cannot create a shared resource itself and fails.

Source

Thrown at upup/pkg/fi/cloudup/awstasks/natgateway.go:309

			return fi.CannotChangeField("ID")
		}
	}
	return nil
}

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

func (_ *NatGateway) RenderAWS(t *awsup.AWSAPITarget, a, e, changes *NatGateway) error {
	// New NGW
	ctx := context.TODO()

	var id *string
	if a == nil {

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

		klog.V(2).Infof("Creating Nat Gateway")

		request := &ec2.CreateNatGatewayInput{
			TagSpecifications: awsup.EC2TagSpecification(ec2types.ResourceTypeNatgateway, e.Tags),
		}
		request.AllocationId = e.ElasticIP.ID
		request.SubnetId = e.Subnet.ID
		response, err := t.Cloud.EC2().CreateNatGateway(ctx, request)
		if err != nil {
			return fmt.Errorf("Error creating Nat Gateway: %v", err)
		}
		e.ID = response.NatGateway.NatGatewayId
		id = e.ID
	} else {
		id = a.ID
	}

View on GitHub (pinned to 4c8573c808)

Solutions

  1. Set the NAT gateway ID in the cluster spec for shared subnets: `kops edit cluster` → subnet spec `id: nat-xxxx`
  2. Remove `shared: true` from the NAT gateway/subnet spec so kops creates and manages the gateway itself
  3. Verify the referenced gateway exists in the target region with `aws ec2 describe-nat-gateways --nat-gateway-ids nat-xxxx`

Example fix

// before
subnets:
- name: private-a
  type: Private
  shared: true
// after
subnets:
- name: private-a
  type: Private
  shared: true
  id: nat-0123456789abcdef0
Defensive patterns

Strategy: validation

Validate before calling

// in cluster spec tooling, before update:
if subnet.Shared && subnet.NatGatewayID == "" {
  return fmt.Errorf("shared subnet %q requires an explicit NAT gateway id", subnet.Name)
}

Type guard

func sharedNatGatewayIDSet(e *NatGateway) bool {
  return !fi.ValueOf(e.Shared) || fi.ValueOf(e.ID) != ""
}

Try / catch

err := applyCluster(ctx)
if err != nil && strings.Contains(err.Error(), "NAT gateway") && strings.Contains(err.Error(), "not found") {
  // set the id: field on the shared subnet spec or drop shared:true
}

Prevention

When it happens

Trigger: NatGateway task with shared: true whose ID is empty/nil — e.g. cluster spec uses a shared/external NAT gateway but `id` wasn't provided in the instance group/subnet spec.

Common situations: Users wiring pre-existing AWS infrastructure into kops (shared VPC) who forget to specify the NAT gateway ID for the subnet; typos in the spec field so the ID never populates.

Related errors


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