kubernetes/kops · error

error deleting EgressOnlyInternetGateway %q: %v

Error message

error deleting EgressOnlyInternetGateway %q: %v

What it means

Thrown when EC2 DeleteEgressOnlyInternetGateway fails with any error other than InvalidEgressOnlyInternetGatewayID.NotFound. Dependency violations (e.g. routes still referencing the gateway) are passed through; everything else is wrapped with the gateway ID. Indicates the IPv6 egress-only gateway could not be removed during cluster teardown.

Source

Thrown at pkg/resources/aws/aws.go:1171

	c := cloud.(awsup.AWSCloud)

	id := r.ID

	{
		klog.V(2).Infof("Deleting EC2 EgressOnlyInternetGateway %q", id)
		request := &ec2.DeleteEgressOnlyInternetGatewayInput{
			EgressOnlyInternetGatewayId: &id,
		}
		_, err := c.EC2().DeleteEgressOnlyInternetGateway(ctx, request)
		if err != nil {
			if IsDependencyViolation(err) {
				return err
			}
			if awsup.AWSErrorCode(err) == "InvalidEgressOnlyInternetGatewayID.NotFound" {
				klog.Infof("Egress-only internet gateway %q not found; assuming already deleted", id)
				return nil
			}
			return fmt.Errorf("error deleting EgressOnlyInternetGateway %q: %v", id, err)
		}
	}

	return nil
}

func ListEgressOnlyInternetGateways(cloud fi.Cloud, vpcID, clusterName string) ([]*resources.Resource, error) {
	gateways, err := DescribeEgressOnlyInternetGateways(cloud)
	if err != nil {
		return nil, err
	}

	var resourceTrackers []*resources.Resource

	for _, o := range gateways {
		resourceTracker := &resources.Resource{
			Name:    FindName(o.Tags),
			ID:      aws.ToString(o.EgressOnlyInternetGatewayId),

View on GitHub (pinned to 4c8573c808)

Solutions

  1. Delete route table entries referencing the egress-only internet gateway, then retry the delete.
  2. Check the embedded AWS error code: AuthFailure/UnauthorizedOperation means fix IAM permissions.
  3. If throttling, wait and re-run kops delete cluster (it is idempotent due to the NotFound check).
  4. Verify the gateway ID format (eigw-...) via `aws ec2 describe-egress-only-internet-gateways`.
Defensive patterns

Strategy: validation

Validate before calling

out, err := ec2Client.DescribeEgressOnlyInternetGateways(ctx, &ec2.DescribeEgressOnlyInternetGatewaysInput{EgressOnlyInternetGatewayIds: []string{id}}); if err != nil || len(out.EgressOnlyInternetGateways) == 0 { /* skip delete */ }

Type guard

func isDependencyViolation(err error) bool { return strings.Contains(err.Error(), "DependencyViolation") }

Try / catch

if err := DeleteEgressOnlyInternetGateway(cloud, r); err != nil {
	var retryErr *resources.DirtyError
	if errors.As(err, &retryErr) { /* retry after routes removed */ }
	log.Printf("eigw %s: %v", r.ID, err)
}

Prevention

When it happens

Trigger: Calling DeleteEgressOnlyInternetGateway on an ID that is still attached to a subnet or referenced by a route table; permission denied on ec2:DeleteEgressOnlyInternetGateway; transient throttling.

Common situations: kops delete cluster blocked because a custom route still points at the egress-only IGW; IAM policy scoped too narrowly; gateway already deleted concurrently but ID malformed.

Related errors


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