kubernetes/kops · error
error deleting ENI %q: %v
Error message
error deleting ENI %q: %v
What it means
kOps wraps the AWS SDK error from ec2.DeleteNetworkInterface in DeleteENI. DependencyViolation errors are returned unmodified (so the resource tracker can retry later), NoSuchEntity is treated as already deleted, and anything else is wrapped with this message. It means the ENI could not be deleted for a reason other than a pending dependency or prior deletion.
Source
Thrown at pkg/resources/aws/eni.go:53
c := cloud.(awsup.AWSCloud)
id := r.ID
klog.V(2).Infof("Deleting EC2 ENI %q", id)
request := &ec2.DeleteNetworkInterfaceInput{
NetworkInterfaceId: &id,
}
_, err := c.EC2().DeleteNetworkInterface(ctx, request)
if err != nil {
if awsup.AWSErrorCode(err) == "InvalidNetworkInterfaceID.NotFound" {
// Concurrently deleted
return nil
}
if IsDependencyViolation(err) {
return err
}
return fmt.Errorf("error deleting ENI %q: %v", id, err)
}
return nil
}
func DumpENI(op *resources.DumpOperation, r *resources.Resource) error {
data := make(map[string]interface{})
data["id"] = r.ID
data["type"] = ec2types.ResourceTypeNetworkInterface
data["raw"] = r.Obj
op.Dump.Resources = append(op.Dump.Resources, data)
return nil
}
func DescribeENIs(cloud fi.Cloud, vpcID, clusterName string) (map[string]ec2types.NetworkInterface, error) {
if vpcID == "" {
return nil, nilView on GitHub (pinned to 4c8573c808)
Solutions
- Check the wrapped error's code; if AccessDenied, grant ec2:DeleteNetworkInterface
- Re-run the delete — kOps retries DependencyViolation cases automatically and treats missing ENIs as success
- Check `aws ec2 describe-network-interfaces --network-interface-ids <id>` for its attachment status
- If throttled, retry after backoff
Defensive patterns
Strategy: retry
Validate before calling
// preflight: confirm ENI exists and is available before delete
out, err := ec2Client.DescribeNetworkInterfaces(ctx, &ec2.DescribeNetworkInterfacesInput{NetworkInterfaceIds: []string{id}})
if err == nil && len(out.NetworkInterfaces) > 0 && out.NetworkInterfaces[0].Status == "available" { /* safe to delete */ } Type guard
func isDependencyViolation(err error) bool {
return awsup.AWSErrorCode(err) == "DependencyViolation" || strings.Contains(err.Error(), "DependencyViolation")
} Try / catch
err := DeleteENI(ctx, cloud, eniID)
switch {
case awsup.AWSErrorCode(err) == "InvalidNetworkInterfaceID.NotFound": // already deleted, ok
case isDependencyViolation(err): // schedule retry later
default: return err
} Prevention
- Retry deletions with backoff — kOps re-runs cleanup on subsequent passes
- Grant ec2:DeleteNetworkInterface broadly or per-VPC
- Check attachment status before manual deletes
- Watch for ENIs held by service-linked resources (ELB, NAT) that must be deleted first
When it happens
Trigger: DeleteNetworkInterface returns an unexpected error: AccessDenied on ec2:DeleteNetworkInterface, AuthFailure/InvalidNetworkInterface.ID.NotFound variants not matched by the pre-checks, throttling, or request serialization failures.
Common situations: IAM policy restricting deletion to specific ENI ARNs; EC2 API throttling during large cluster teardown; ENI attached to a resource that keeps returning errors other than DependencyViolation (e.g. service-linked state).
Related errors
- unexpected number of network interfaces for instance %q: %v
- error terminating instances: %v
- error deleting KeyPair %q: %v
- error deleting EgressOnlyInternetGateway %q: %v
- error deleting ec2 LaunchTemplate %q: %v
AI-assisted analysis of kubernetes/kops@4c8573c808 (2026-09-05).
Data as JSON: /api/errors/e5257895ed933cf8.
Report an issue: GitHub.