Unused Elastic Network Interfaces: the basics
Why a leftover network card is a hygiene problem with a hidden price tag
An Elastic Network Interface (ENI) is the virtual network card that a workload uses to talk to the rest of the VPC — it carries the private IP, optional public/Elastic IP, MAC address, security groups, and subnet placement for an instance or a managed service. When something is deleted or detached, its ENI can be left behind in the available state: allocated to your account, attached to nothing, doing no work. The ENI object itself is not a billed line item — AWS does not charge a per-hour fee for an idle network interface.
So why does it land on a wastage report? Two reasons. First, a detached ENI frequently still holds an associated public IPv4 or Elastic IP, and that is billed — roughly $0.005/hour, about $3.65/month, since the February 2024 universal IPv4 charge. An orphaned ENI is therefore often a hidden IPv4 charge wearing a network-card costume. Second, leftover ENIs are a strong orphan signal — they're the residue of terminated instances, deleted Lambda VPC attachments, removed load balancers, and stale interface VPC endpoints — and they block deletion of the security groups and subnets they reference, gumming up every other cleanup you try to run.
The trap is telling a true orphan from a service-reserved interface. Many ENIs in the available or in-use state belong to AWS managed services — RDS, Lambda, NAT Gateways, interface VPC endpoints, ELB — and are flagged RequesterManaged=true. Those must never be hand-deleted; AWS owns their lifecycle and will recreate or error on them. A genuinely safe-to-delete ENI is one that is both detached (status=available, Attachment=null) and not requester-managed (RequesterManaged=false).
In this lesson you'll learn why an ENI itself isn't directly billed, and where the real value lives instead: reclaiming the public IPv4 charges that hide on detached interfaces, restoring the ability to delete blocked security groups and subnets, and using the orphan count as a cleanup-discipline signal. You'll see the AWS CLI commands to list every available interface, the single most important filter — distinguishing a true orphan (RequesterManaged=false) from a service-reserved one belonging to RDS, Lambda, NAT, interface VPC endpoints, or ELB — and the safe delete pattern. You'll also see the edge cases that bite: requester-managed ENIs that error or silently respawn, and the off-platform references that any attached public IP might still carry.
The interfaces that wouldn't let go
A common AWS support ticket reads: "I'm trying to delete a security group and AWS says it's still in use, but I've deleted everything that used it." Nine times out of ten the culprit is a forgotten ENI — a network interface left in the available state by a deleted Lambda VPC function or a removed load balancer — still referencing that security group. The group can't be deleted until the interface is. One platform team auditing a VPC they thought was empty found 318 detached ENIs blocking the teardown of an entire account they were trying to decommission; 71 of them still carried a billed public IPv4 address. The cleanup wasn't about the interfaces — it was about everything they were quietly holding hostage.
Cleaning up unused ENIs in action
Marco runs the monthly FinOps cadence at a media company with a sprawling legacy VPC. The dashboard flags 64 network interfaces in the available state. He knows the interface count itself isn't a dollar figure — what catches his eye is that 22 of them still have an associated public IPv4, which is real money, and that an account-decommission ticket has been stuck for weeks because a subnet "won't delete."
Marco doesn't bulk-delete. The first filter is the one that matters: he checks RequesterManaged on every interface. Of the 64, 19 turn out to be requester-managed — interface VPC endpoints, a couple of RDS instances, and Lambda functions with VPC access — and those are off-limits entirely; deleting them by hand either errors out or has AWS silently recreate them. He tags those Lifecycle=managed and moves on.
That leaves 45 genuinely orphaned interfaces: Attachment=null, RequesterManaged=false, residue of terminated instances and a load balancer deleted last quarter. For the 22 carrying a public IP he confirms nothing off-platform references the address, then deletes all 45 in one scripted pass. The stuck subnet deletes cleanly the moment its last ENI is gone, the decommission ticket closes, and ~$80/month of hidden IPv4 charges drop off. Elapsed time: about twenty minutes, most of it the managed-versus-orphan check.
First, list every network interface in the available (detached) state, showing whether it's requester-managed and whether it carries a public IP. The RequesterManaged flag is the single most important column — true means AWS owns it.
Detached interfaces with RequesterManaged=False are the safe-to-delete orphans; True belongs to a managed service and must be left alone.
Once you've confirmed the interface is detached (Attachment=null), not requester-managed, and that any attached public IP has no off-platform references, delete it by ID.
Delete is immediate. On a requester-managed interface it errors out — that's AWS protecting a resource it owns, and the signal to leave it alone.
Network interfaces under the hooddeep dive
An ENI bundles the network identity of a workload: one primary and optional secondary private IPs, an optional public IPv4 or associated Elastic IP, a MAC address, a list of security groups, a source/dest-check flag, and its subnet/AZ placement. The interface object is free — there is no per-hour charge for an ENI in any state. What costs money is anything billed that rides on it: most commonly an associated public IPv4 address, metered at $0.005/hour (~$3.65/month) since the February 2024 universal IPv4 charge. So the cost of an orphaned ENI is exactly the cost of whatever address it's still holding, and zero if it holds none.
The two state fields that decide whether an interface is safe to touch are Attachment and RequesterManaged. A detached interface has status=available and a null Attachment — it's wired to nothing. But detached doesn't mean deletable: RequesterManaged=true marks an interface that AWS provisioned on your behalf for a managed service — RDS, Lambda VPC access, NAT Gateways, interface VPC endpoints (ela-...), ELB/ALB/NLB. Those have their lifecycle owned by the service; hand-deleting one either returns an authorization error or, worse, succeeds momentarily before the service recreates it. The unambiguous safe target is status=available AND RequesterManaged=false.
Two further mechanics matter. First, terminating an instance auto-detaches its ENI but, depending on the DeleteOnTermination flag, may leave the interface behind in available state — that's a primary source of orphans. Second, a detached non-managed ENI still pins its security groups and subnet: AWS refuses to delete a security group or subnet while any interface references it, which is why these leftovers surface as "can't delete, still in use" errors during teardown. Deleting the orphan ENI is frequently the unlock for a whole chain of blocked cleanup.
# List only the SAFE deletion candidates: detached AND not requester-managed.
# Anything RequesterManaged=true (RDS, Lambda, NAT, VPC endpoints, ELB) is excluded.
aws ec2 describe-network-interfaces \
--filters Name=status,Values=available \
--query "NetworkInterfaces[?RequesterManaged==\`false\`].\
{Id:NetworkInterfaceId,PublicIp:Association.PublicIp,SG:Groups[].GroupId,Subnet:SubnetId}" \
--output table
# Inspect one before deleting — confirm Attachment is null and check for a billed IP.
aws ec2 describe-network-interfaces \
--network-interface-ids eni-0aa11bb22cc33dd \
--query 'NetworkInterfaces[0].{Attachment:Attachment,Managed:RequesterManaged,PublicIp:Association.PublicIp}' What is the impact of unused Elastic Network Interfaces?
The direct cost of the interfaces themselves is zero — AWS doesn't meter an idle ENI. The real dollar impact is the public IPv4 addresses that hide on a subset of them: each carried address is ~$3.65/month since the 2024 universal IPv4 charge, so 50 orphaned ENIs of which 20 still hold a public IP is ~$73/month of charge that's invisible unless you look at the interface level. The orphan that carries no address costs nothing directly — its impact is entirely the hygiene and blocking problem below.
The bigger operational cost is that leftover ENIs block other cleanup. A detached non-managed interface pins the security groups and subnet it references, so AWS refuses to delete those while it exists. That's how a routine VPC or account teardown stalls for weeks on a cryptic "resource still in use" error, and how a single forgotten interface can hold an entire decommission hostage. The saving from deleting the ENI is small; the value is unblocking everything downstream of it.
There's a discrimination cost too — the risk of cleaning up the wrong thing. A large fraction of available interfaces belong to AWS-managed services (RDS, Lambda, NAT, interface VPC endpoints, ELB) and are flagged RequesterManaged=true. Delete one of those by hand and you either hit an authorization error or trigger a confusing respawn, and a careless bulk script that ignores the flag can cause an outage. So the work is precision cleanup, not volume cleanup: the value is in correctly separating the true orphans from the service-reserved interfaces, every time.
Finally, an orphaned interface that still carries a public address is a small attack-surface and audit item, not just a cost one. An address that resolves in DNS but points at a dead interface, or one a partner still allowlists, is exactly the loose end a security review surfaces. Reclaiming orphans tightens the network surface and shortens the inventory at the same time — the cost report is just the easiest place to notice the mess.
How do you delete unused network interfaces safely?
Cleanup is a four-step loop: inventory every detached interface, separate the true orphans from service-managed ones, check any attached address for off-platform references, then delete the confirmed orphans and adopt conventions so they don't come back.
1. Inventory every interface in the available state
Run describe-network-interfaces --filters Name=status,Values=available in every region and account. Capture the interface ID, Description, RequesterManaged, any Association.PublicIp, the security groups it references, and its subnet. The available status with a null Attachment is what makes it detached; the rest of the fields tell you whether it's safe to touch and whether it's actually costing anything.
2. Separate true orphans from service-managed interfaces
This is the safety-critical filter. Exclude every interface with RequesterManaged=true — those belong to RDS, Lambda VPC access, NAT Gateways, interface VPC endpoints (ela-...), and ELB/ALB/NLB, and AWS owns their lifecycle. Hand-deleting one errors out or triggers a silent respawn, and a bulk script that ignores the flag can cause an outage. Only interfaces that are available AND RequesterManaged=false are genuine orphans. Tag the managed ones Lifecycle=managed so the next audit skips them.
3. Check any attached public IP for off-platform references
For each orphan that carries a public IPv4 or Elastic IP, the same caveat as any address applies: confirm nothing off-platform points at it — no DNS A record, no customer or partner firewall allowlist, no BYOIP dependency — before you let the address go. Deleting the interface releases or strands that address, and you won't get the same IP back. For orphans with no attached address there's no IP risk; the only thing to confirm is that they're genuinely detached and non-managed.
4. Delete the confirmed orphans and prevent recurrence
For interfaces that cleared the checks, call delete-network-interface --network-interface-id eni-.... Deleting the orphan also unblocks the security groups and subnets it pinned, so chain the cleanup. To stop new orphans, make deleting leftover interfaces part of the same change that retires a resource, set DeleteOnTermination=true on instance ENIs, and add an AWS Config rule or scheduled job that flags long-lived available, non-managed interfaces so the next teardown isn't blocked.
# Delete ONLY detached, non-managed interfaces. The RequesterManaged filter is
# the safety gate — never delete an interface AWS provisioned for a service.
REGION=us-east-1
ORPHANS=$(aws ec2 describe-network-interfaces --region $REGION \
--filters Name=status,Values=available \
--query "NetworkInterfaces[?RequesterManaged==\`false\`].NetworkInterfaceId" \
--output text)
for eni in $ORPHANS; do
# Check for a billed public IP and confirm DNS/allowlist before this point.
ip=$(aws ec2 describe-network-interfaces --region $REGION \
--network-interface-ids "$eni" \
--query 'NetworkInterfaces[0].Association.PublicIp' --output text)
echo "Deleting $eni (public IP: $ip)"
aws ec2 delete-network-interface --region $REGION --network-interface-id "$eni"
done
# Their security groups and subnets can now be deleted — the block is cleared. Quick quiz
Question 1 of 5You find a network interface in the available state. Before deciding to delete it, what's the single most important thing to confirm?
You scored
0 / 5
Keep learning
Dig deeper into ENI mechanics, the public IPv4 charge that hides on them, and the cleanup discipline that keeps the category small.
- Elastic network interfaces — Amazon VPC User Guide Authoritative reference on ENI attributes, attachment states, requester-managed interfaces, and how to create, detach, and delete them.
- Requester-managed network interfaces Explains which AWS services provision ENIs on your behalf (RDS, Lambda, VPC endpoints, ELB, NAT) and why you must not delete them by hand.
- New — AWS Public IPv4 Address Charge AWS announcement of the February 2024 $0.005/hour charge on all public IPv4 addresses — the charge that hides on detached interfaces.
- FinOps Foundation — Cloud Rate and Usage Optimization How resource-cleanup discipline and closing the decommission loop fit the broader FinOps lifecycle and operating model.
You've completed Delete unused Elastic Network Interfaces. You now know that the interface itself isn't billed — the value is in the public IPv4 charges that hide on detached interfaces and in unblocking the security groups and subnets they pin. You know the one filter that makes this safe: a true orphan is status=available AND RequesterManaged=false, while a requester-managed interface (RDS, Lambda, NAT, VPC endpoint, ELB) must be left to AWS. Next time the wastage report flags an unused interface, you'll have a defensible path from "flagged" to "deleted" — and you'll know which ones never to touch.