Our Undo Button for Releasing an Elastic IP Was Wrong
Our fix flow offered to undo an Elastic IP release. The undo gave you a different IP and a new charge. Here is what AWS says about recovery and what we changed.

On 2026-11-08 we audited our own fix flow. We found two places where the product said something that was not true. The first one is about a button you hope never to need: Undo.
The problem
CloudWise's fix flow can release an Elastic IP address that is attached to nothing. Every fix has a plan, and a plan can carry an undo. For a released address, the undo ran allocate_address.
As we sent it, that call hands out a new address. It does not ask for the old one back. So you got a different public IP, a new charge for it, and a scanner that will flag it as waste on the next run. The plan said "undo". What it actually did was buy a different IP.
We found it by reading our own plans against what AWS really does. It had to go.
What AWS says
The AWS page on releasing an Elastic IP address is careful. After you release an address, "you might be able to recover" it. Then come the rules:
- You can't recover it if it has been allocated to another AWS account, or if recovering it would take you over your Elastic IP address limit.
- You can't recover tags associated with it.
Recovery is possible, then, but only if nobody else has taken the address and you still have room under your limit. A release is not a pause. Whether you get the address back depends on things outside your account. AWS's own recovery call passes the old address to allocate-address. Ours did not.
Recovery is never guaranteed, so we stopped treating a release as something we can reverse.
What we changed
We do not promise what AWS does not promise. So:
- Both Elastic IP checks (an address attached to nothing, and an address held by a stopped instance) are now on the list of fixes that cannot be undone.
- Those plans carry no undo. They say "Not undoable: a released IP cannot be reclaimed."
- The API refuses a rollback request for those two types.
- Plans that were already stored are not rewritten. They keep what they said when they were made.
We also changed the approval step. A plan with no undo, and a saving above a small monthly threshold, now asks you to type the resource id before the Approve button works. The match is exact and case sensitive. Bulk approve skips those plans, so each one goes through its own approval. Fixes you can undo keep one-click approval.
The point is that the cost of being wrong should sit next to the button. An irreversible fix is not a bigger version of a reversible one. It is a different decision, and the interface should treat it that way.
The second thing: the safety snapshot
Before the fix flow deletes an EBS volume, it takes a snapshot. That is the safety net. We had a problem with it too, and it was the opposite problem.
The snapshot was kept forever, and a snapshot bills for as long as it exists. So the saving we showed for a volume delete was overstated: part of it was quietly replaced by the snapshot's own storage bill. The undo also had a flaw. It recreated the volume with the defaults of the create call, which means no tags and a different type, not the volume you deleted.
What we changed:
- The snapshot taken ahead of a volume delete is tagged with the action id and an expiry 30 days later.
- The executor records the deleted volume's Availability Zone, type, IOPS, throughput, multi-attach setting and tags when it takes the snapshot. An undo restores them.
- The plan says what the undo really does: it creates a new volume from the snapshot, with a new volume id.
- A daily sweep deletes an expired snapshot, but only when every one of these holds: the expiry has passed, the action is finished, no undo is still possible, AWS still shows both tags naming that action, no tag your policy excludes is on it, the account is still connected, remediation is enabled for you, and the kill switch is on.
What is not finished
Two honest notes, because a post about wrong claims should not make new ones.
- The sweep ships as a dry run. It lists what it would delete and deletes nothing, and it has not yet been exercised on staging.
- One case is still open. If an undo fails, the snapshot may be the only copy of the data, so the sweep keeps it for now. We have not decided whether to delete it after 30 days like the others, keep it until you delete it, or tell you first.
What to take from it
If you run your own cleanup scripts, look at what your undo really does. For each automated delete, ask:
- Is the thing recreated, or is a new thing created that looks like it?
- Does the undo carry the settings of the original, or the defaults of the create call?
- Is the safety net billed? If so, when does it expire, and who deletes it?
Run it yourself
The CLI is free and source-available (FSL-1.1-ALv2). It runs on your machine, reads your AWS account with your own credentials, and sends nothing to CloudWise. It only reads. The fix flow in this post is part of the hosted product.
pip install cloudcostwise
cloudcostwise scan --profile my-profile --regions all
Read-only and free, in a few minutes. AWS bills the scan's Cost Explorer calls; add --no-cost-explorer to skip them. Start at cloudcostwise.io. The full list of checks is on the waste checks page.
Find this waste in your own account
Run the free scanner on your own machine. Read-only, no signup, and nothing is sent to CloudWise unless you choose to share a summary at the end.
$ pipx install cloudcostwise
What it checksPrefer a dashboard? Start a free hosted scan →