What triggers this finding
An allocated Elastic IP address that is not associated with a running instance (no association ID).
Typical fix
Release Elastic IPs you no longer need. Remember to update DNS records if the IP was referenced externally.
Example savings
About $3.65/month per unused Elastic IP in most regions.
See also: Severity and savings estimates for how Parsivex calculates figures on your report.
What Parsivex counts, and what AWS bills
Every public IPv4 address in an AWS account carries an hourly charge, whether it is attached to something or not. Parsivex prices an unassociated Elastic IP at $3.65 a month — the $0.005 hourly rate over 730 hours — and multiplies by the number it finds, reporting them as a single rolled-up finding per region rather than one finding per address.
The finding's scope is narrower than the charge's. Parsivex flags addresses with no AssociationId at all, which is the clearest case of paying for nothing. AWS bills a broader set than that, so this finding is a lower bound on your IPv4 line rather than a full account of it. Two gaps are worth knowing:
An Elastic IP attached to a stopped instance keeps its association, so it does not appear here — while still billing every hour the instance sits stopped. That combination usually shows up as an idle EC2 finding instead, and the address is part of what makes stopping less of a saving than it looks.
Auto-assigned public IPv4 addresses on running instances, and the addresses attached to public load balancers, are billed on the same meter and are not Elastic IPs at all. Neither is in scope here.
Severity is always low, regardless of count, because $3.65 is genuinely small. The count is what makes the finding interesting: forty stranded addresses is $146 a month, and accounts that have been through several years of teardowns routinely have them.
Listing unassociated addresses
aws ec2 describe-addresses \
--query 'Addresses[?AssociationId==null].[AllocationId,PublicIp,Domain,Tags[?Key==`Name`].Value|[0]]' \
--output table
That query is the detector's rule expressed directly. Everything it returns is in the finding, and Parsivex records the same allocation IDs and public addresses so the two lists can be compared line for line.
Addresses held deliberately
An Elastic IP is one of the few AWS resources whose value is its name rather than its capacity, and that changes the calculus completely. The address itself is the asset, and once released it cannot be recovered.
- Allowlisted addresses. A partner, bank, or vendor has this specific IP in a firewall rule. Getting it re-added is a change-request process measured in weeks, and the address you released will not come back.
- DNS records. An A record pointing at the address, possibly with a long TTL, possibly in a zone you do not control.
- Cutovers in progress. Blue/green migrations and instance rebuilds routinely leave an address unassociated for hours or days between steps.
- Reserved capacity for known workloads. Addresses held so that a seasonal or scheduled system comes back on the same IP it had last time.
- Mail and reputation. An address with established sending reputation is worth far more than $3.65 a month, and reputation does not transfer.
- BYOIP ranges. Addresses from a customer-owned prefix behave differently on both billing and release. Check the pool before treating them as ordinary allocations.
Tags are the practical discriminator. An address with an owner tag and a purpose is almost always one of the above; an untagged one left over from an instance terminated two years ago is almost always not.
Release is the one irreversible networking fix
release-address returns the address to the regional pool immediately, and there is no undo, no grace period, and no way to request that specific address again. Within minutes it can be allocated to a completely unrelated AWS customer.
The failure mode is what makes this worth care out of proportion to the cost. Nothing errors when a released address is needed again. Allowlists simply stop matching, so connections time out rather than being refused; DNS keeps resolving to an address that now belongs to somebody else, so traffic reaches a stranger's infrastructure rather than failing. Both look like intermittent network problems and neither points at the release that caused them.
Because the finding is low severity and cheap to defer, the sensible sequence is not to release immediately. Tag each address with an owner and a review date, check DNS and any allowlist documentation against the public addresses in the finding, and release only the ones that survive that check. The finding will still be there next scan, and $3.65 a month is a small price for a week of certainty.
Where addresses are being stranded repeatedly, the durable fix is upstream: set DeleteOnTermination behaviour deliberately on the interfaces that hold them, or move to a load balancer or Global Accelerator for workloads that need a stable public address across instance replacements.