CloudFormation ROLLBACK_COMPLETE: How to Fix It Fast
To fix ROLLBACK_COMPLETE, read the first CREATE_FAILED event, fix that cause, delete the stack, and create it again. ROLLBACK_COMPLETE means your stack's very first creation attempt failed, CloudFormation deleted every resource it had managed to build, and the stack is now stuck in a dead end that flatly refuses updates. Here's the part that catches people off guard: it doesn't just undo the one resource that broke. By default, CloudFormation treats a first-time creation as all-or-nothing, so if resource seven out of ten fails, resources one through six get torn down too, even though they deployed perfectly fine.
Jake found this out on a Thursday night, which is somehow always when it happens. He runs a small phone repair shop, and for a few months he'd been paying a freelancer to build him an AWS-hosted app that tracks repair tickets and texts customers when their phone is ready. The freelancer had moved on, so Jake was on his own, following a README that said "just run this CloudFormation template," ahead of a weekend trade-in promotion he'd already advertised on Instagram. He ran it. It failed. He tried to run it again to "just fix the one thing." CloudFormation told him no, flatly, with an error he'd never seen before.
He called his cousin Ethan, who'd talked him through AWS billing panic once before and had become, by unspoken agreement, Jake's on-call AWS person. "It says ROLLBACK_COMPLETE," Jake read off his screen. "Is that good? It sounds like it finished." Ethan laughed, not unkindly. "It finished, alright. It finished failing. That word 'complete' is doing a lot of work in that sentence — it means the cleanup is complete, not the job."
🙋♂️ Jake's Reality Check
"I just wanted to add one more field to the form. Why is it acting like I tried to blow up my whole account?"
Because as far as CloudFormation is concerned, you never actually finished building this stack the first time. ROLLBACK_COMPLETE isn't "your app is broken." It's "your app was never fully born." CloudFormation treats an incomplete birth and a change to something that's already alive as two completely different operations, and it will only let you do the second one.
What ROLLBACK_COMPLETE actually means
Every CloudFormation stack moves through a lifecycle, and the state names are trying to tell you a story about where in that lifecycle things went sideways. When you create a brand-new stack, CloudFormation's plan is simple: build every resource in the template, one by one, in dependency order. If all of them succeed, the stack lands in CREATE_COMPLETE. If even one fails, CloudFormation stops moving forward and starts moving backward — deleting the resources it already created, in reverse order, trying to leave your account exactly as clean as it found it.
That backward pass has its own statuses. While it's happening, the stack shows ROLLBACK_IN_PROGRESS. If CloudFormation manages to delete everything it created without hitting a second snag, the stack settles into ROLLBACK_COMPLETE. That status is CloudFormation telling you, plainly: the thing you asked me to build, I could not fully build, and I have already cleaned up after myself. It's a terminal state, not an error that resolved itself — a dead end with one specific exit.
Here's the distinction that trips up more people than any other single fact about this error: ROLLBACK_COMPLETE only happens on a stack creation that failed. If you already had a working stack and an update to it failed, and the rollback of that update couldn't complete either, you land in a different, similarly-named state instead: UPDATE_ROLLBACK_FAILED. Those two look almost identical in a message someone pastes you at 11pm, and the fixes are completely different, so it gets its own warning before we go any further.
⚠️ The advice that's wrong for your situation
A lot of guides tell you to run continue-update-rollback whenever a stack seems stuck. That command exists to move a stack from UPDATE_ROLLBACK_FAILED to UPDATE_ROLLBACK_COMPLETE — it has nothing to do with ROLLBACK_COMPLETE, which came from a failed creation, not a failed update. Run it against a ROLLBACK_COMPLETE stack and the API rejects the call outright, because there was never a stable prior version of the stack for it to roll back to. If your stack was never in a working state before this attempt, you're in the creation-failure branch, and the fix is delete-then-recreate, not continue-update-rollback.
"Think of it like this," Ethan told Jake once he'd pulled up the console himself, screen-sharing over a video call. "Updating a stack is like renovating a house that's already standing. Creating one is pouring the foundation. If the foundation pour goes wrong halfway through, there's no house yet to renovate — you don't call a contractor to 'update' a hole in the ground. You fill the hole back in and pour it again." Jake pushed back, a little annoyed: "Okay, but why does it have to tear down the parts of the foundation that actually set properly? Why not just fix the bad corner?" Ethan didn't dodge it. "Because by default, AWS doesn't trust a partially-poured foundation to be safe to build on top of later. It's being conservative on your behalf. You can actually tell it to leave the good parts standing next time — we'll get to that, because it would've saved you twenty minutes tonight."
| Stack status | What actually happened | Can you update it directly? |
|---|---|---|
ROLLBACK_COMPLETE |
A brand-new stack's creation failed and CloudFormation finished cleaning up. | No. Delete and recreate. |
UPDATE_ROLLBACK_FAILED |
An existing stack's update failed, and rolling back to the previous version also failed. | No, but yes to continue-update-rollback. |
UPDATE_ROLLBACK_COMPLETE |
An update failed, but the stack successfully rolled back to its previous, working version. | Yes, normally. |
ROLLBACK_FAILED |
A brand-new stack's creation failed, and cleaning up after itself also failed. | No. Retry the rollback or delete. |
✅ Why this rule exists, and why it's the right one
CloudFormation's entire value proposition is that your stack matches your template, every time, with no drift and no half-finished guesses. Letting you "update" a stack that never successfully finished creating would mean CloudFormation has to reconcile a template against resources that may or may not exist, in an unknown mix of states. Rather than guess, it refuses. That's frustrating in the moment, but it's the same discipline that keeps your infrastructure reproducible six months from now.
Finding the real error underneath the rollback
"ROLLBACK_COMPLETE" is CloudFormation's summary of the outcome, not its explanation of the cause. It's the equivalent of a doctor telling you "the patient stabilized" without saying what was wrong in the first place. To fix anything, you need the actual reason a specific resource refused to create, and CloudFormation records that reason as plain English text on every failed resource event. You just have to know where to look, because the console doesn't put it front and center by default.
Reading it in the console
- Open the CloudFormation console and pick the AWS Region your stack is actually in — a stack in
us-east-1is invisible from theeu-west-1console, and "I can't even find my stack" is its own minor panic that has nothing to do with rollback. - Click into the stack and open the Events tab.
- Events are listed newest first, so scroll down (chronologically backward) until you find the first row whose Status column says
CREATE_FAILED. That first one is the resource that actually broke; everything below it — theROLLBACK_IN_PROGRESSand laterDELETE_IN_PROGRESSrows for other resources — is just CloudFormation cleaning up the mess that first failure caused. - Read the Status reason column on that row. This is almost always a direct, human-readable error from the underlying AWS service — something like "Bucket already exists," or a specific IAM error naming the exact action you're missing.
Newer CloudFormation deployments also tag events with an operation ID, which lets you filter the whole events list down to just the operation that failed instead of scrolling through everything the stack has ever done. If your stack has a long history of attempts, clicking that operation ID and viewing it as its own focused list saves a lot of scrolling.
Reading it from the command line
If you'd rather not click through a UI, or you're troubleshooting inside a script or a CI pipeline, the AWS CLI gives you the same information in one command:
aws cloudformation describe-stack-events \
--stack-name your-stack-name \
--query "StackEvents[?ResourceStatus=='CREATE_FAILED'].[LogicalResourceId,ResourceStatusReason]" \
--output table
That single query filters out every noisy in-progress and cleanup event and hands you exactly two columns: which logical resource in your template failed, and why. If the output is empty, double-check the stack name and Region — an empty result almost always means you're pointed at the wrong stack, not that CloudFormation forgot to log the failure.
Ethan pulled this exact command up on the shared screen while Jake watched. "See, it's telling you right here — 'S3 bucket already exists.' That's it. That's the whole mystery." Jake stared at it. "That's all this was? A name?" "A name," Ethan confirmed. "The freelancer hardcoded a bucket name in the template instead of letting AWS pick one for you, and somebody else on the planet already owns that exact name. It's not personal. S3 bucket names are unique across every AWS account that exists, not just yours."
🙋♂️ Jake's Reality Check
"I found like forty rows in that Events tab and half of them say FAILED. Which one do I actually care about?"
Only the very first CREATE_FAILED row, scrolling from the bottom up in time. Everything after it — more failed rows, rollback rows, delete rows — is downstream noise caused by that first failure. Fix the first one and the rest of that pile of red rows won't happen again next time.
The causes, ranked by how often they actually happen
Once you have the exact status reason, it almost always falls into one of a handful of buckets. Here's how to read each one and what actually fixes it, cheapest and simplest fix first.
Insufficient IAM permissions
This is the single most common cause, and Ethan will tell anyone who asks that it's the first thing he checks, every time, before he reads another word of an error message. When you create a stack, CloudFormation doesn't quietly get some magic elevated access — it acts either with your own IAM credentials or with a service role you've explicitly attached to the stack. If that identity isn't allowed to create the specific resource type in your template, that resource fails, and the whole stack rolls back with it. The telltale status reason names the exact action and resource: something like an EC2 security group action, or an S3 bucket action, saying the user or role isn't authorized to perform it. You need permission not just for CloudFormation itself, but for every underlying service your template touches — S3, EC2, IAM, Lambda, whatever's actually in the resource list.
The fix is either to add the missing permission to whichever identity is deploying the stack, or, cleaner for anything beyond a one-off personal account, to attach a dedicated CloudFormation service role with exactly the permissions that stack needs, so your deploying user doesn't need broad access at all. If your template itself creates IAM resources — roles, policies, users — you also need to explicitly acknowledge that in the create-stack call or the console checkbox, or CloudFormation stops you before it even tries, with an insufficient-capabilities error rather than letting it fail mid-build.
A resource name that's already taken
Plenty of resource types let you hardcode a specific name — an S3 bucket name, an IAM role name, a specific DynamoDB table name. Names like this have to be unique, sometimes globally, the way S3 bucket names are unique across every AWS account on the planet, not just yours. If you, or an earlier failed attempt, already created something with that exact name, or someone else entirely already grabbed it, the create call for that resource fails outright with a message saying the resource, or a resource with that name, already exists. The cheap fix is to remove the hardcoded name and let CloudFormation generate a unique one for you, which is what most templates should do by default unless there's a specific reason a name has to be predictable. The other fix, when you genuinely do need that exact name and the existing thing is something you own, is to import the existing resource into the stack instead of trying to create a duplicate.
An account quota you've bumped into
Every AWS account has default service quotas — how many EC2 On-Demand instances you can run at once, how many VPCs per Region, and so on. If your template tries to create more of something than your account is allowed, the resource creation fails with a status reason mentioning the limit. The classic example is the default cap on On-Demand EC2 instances; try to launch past it in one stack and you'll see a start-failed status on the instance itself. There's a second, sneakier version of this: during an update that replaces a resource, CloudFormation creates the new one before deleting the old one, which can briefly push you over quota even if your steady-state usage is well under it. Either delete resources you don't need, or request a quota increase through the Service Quotas console before you retry.
An invalid property value or a resource that doesn't exist
If your template references something that has to already exist — a specific EC2 key pair name, a VPC ID, a security group ID — and it doesn't exist in that account and Region, or you typo'd it, the resource fails at creation with a validation-style error. This is also where you'll see errors for using a security group's name where the resource actually needed its ID, which is a specific, well-documented trap for anything referencing a security group inside a VPC rather than the account's old-style default security groups. Fix the value in the template, confirm the referenced resource actually exists in the same account and Region as the stack, and retry.
A resource that never stabilized in time
Some resources take a while to fully come up, and CloudFormation waits for a signal that they're ready before moving on — an Auto Scaling group waiting for instances to report healthy, an RDS instance finishing its initial setup, a nested stack finishing its own creation. If that resource doesn't respond inside CloudFormation's timeout window, or the AWS service backing it had a genuine interruption, the resource fails to stabilize and the stack rolls back even though nothing was really wrong with your template. Check the relevant AWS service's status first. If the service was healthy, the real fix for resources with known long provisioning times is to attach a CloudFormation service role and lean on that role's handling of these longer operations, since the timeout period depends partly on the credentials used to perform the operation.
A dependency CloudFormation couldn't infer on its own
CloudFormation usually figures out the right build order from how resources reference each other in the template. Occasionally it can't — a classic example is an Elastic IP that needs an internet gateway attachment to exist first, but nothing in the template's normal property references makes that relationship explicit. The fix is an explicit DependsOn attribute on the resource that needs to wait, telling CloudFormation directly what has to finish first.
| Status reason mentions | Likely cause | Cheapest fix |
|---|---|---|
| "not authorized to perform" | IAM permissions | Add the named action to the deploying identity, or use a service role |
| "already exists" | Hardcoded, taken resource name | Remove the fixed name, or import the existing resource |
| "limit exceeded" / "start_failed" | Account service quota | Delete unused resources or request a quota increase |
| a property/type validation message | Bad or missing referenced resource | Fix the value; confirm the referenced resource exists in-account and in-Region |
| "failed to stabilize" / timeout | Slow resource, or a real service interruption | Check AWS service health, then attach a service role for longer operations |
| a dependency/ordering error | CloudFormation couldn't infer build order | Add an explicit DependsOn attribute |
When it's a nested stack: tracing the failure one layer down
If your template uses nested stacks — a parent template that includes an AWS::CloudFormation::Stack resource pointing at a child template — the parent's Events tab often just tells you "the nested stack resource failed," without the actual underlying reason. The real cause lives inside the child stack's own event history, and you have to open a second layer to find it.
- In the parent stack's Resources tab, find the logical ID whose type is
AWS::CloudFormation::Stackand whose status showsCREATE_FAILED. Its Physical ID is the actual stack ARN of the child. - Open that child stack's own Events tab (or run
describe-stack-eventsagainst its stack name or ARN directly). - Repeat the same search for the first
CREATE_FAILEDrow inside the child. That's the real root cause — the parent's failure was just it noticing the child didn't finish.
Nested stacks add one more wrinkle worth knowing before you try to clean up: if one nested stack fails to roll back, CloudFormation halts every other nested stack's cleanup too, regardless of what state they're individually in, because of the dependencies that can exist between them. That's why you sometimes see sibling nested stacks stuck in states like UPDATE_ROLLBACK_COMPLETE_CLEANUP_IN_PROGRESS that never seem to finish on their own — they finished their own part, but they're waiting on a signal from a stack that never came, because that other stack is the one that's actually broken. If you hit that specific stuck state and none of the usual fixes clear it, that's one of the few situations in CloudFormation where opening an AWS Support case is the documented next step rather than a fallback of last resort.
⚠️ Don't touch resources by hand to "help"
It's tempting, when a nested stack is stuck, to go delete the orphaned resource yourself in the underlying service's console to force things along. Don't. CloudFormation doesn't know you did that, and the next operation it tries against that stack will assume the resource still exists in the state it last recorded — which is exactly the mechanism that causes the separate, even worse UPDATE_ROLLBACK_FAILED state on other stacks. If you have to touch something manually, do it only as a last resort and only after you've already decided you're deleting the whole stack anyway.
Catching it before you ever create the stack
CloudFormation doesn't wait until it's halfway through building your stack to catch every mistake. It runs a pre-deployment validation pass first, and a growing share of what used to cause a mid-build rollback now gets caught before a single resource is ever touched. Three specific validation failures stop the operation immediately, before anything is provisioned: property syntax validation, which catches values that don't match the expected schema — an invalid ARN pattern, a string where an integer belongs, an invalid value in an enum, or a required property that's simply missing; resource name conflicts, where a name in your template already exists in your account and the resource type in question doesn't support reusing an existing name; and service quota warnings, flagging when what you're about to create would exceed a current quota before CloudFormation lets you find that out the hard way mid-rollback.
When validation catches something, the console's Events tab shows the operation ID, and clicking through to the Deployment validations tab on that operation gives you the exact property path where the problem sits — not a vague complaint, a precise pointer. Occasionally validation flags something that's actually a false positive for your specific case; if you've confirmed that and need to proceed anyway, the CLI's --disable-validation flag (or setting DisableValidation to true through the API) lets you push past it deliberately, rather than fighting the console.
Before any of that even runs against real AWS infrastructure, you can validate the template on its own, for free, with no resources touched at all:
aws cloudformation validate-template --template-body file://template.yaml
This checks that the file is valid JSON or YAML and returns the parameters and capabilities CloudFormation found in it. It's a syntax and structure check, not a guarantee the stack will deploy cleanly — it won't catch a taken S3 bucket name or a missing IAM permission, because those depend on your live account state, not the template text. Think of it as making sure the blueprint is legible before anyone shows up with concrete. It's a five-second habit that catches an embarrassing share of typos before they ever get the chance to become a 40-row Events tab.
Fixing it: delete the stack, then create it again
Once you know why creation failed and you've fixed it in your template or your account, the actual recovery step is almost anticlimactic: delete the ROLLBACK_COMPLETE stack, then create a new one from the corrected template, using the same stack name if you like — the old one is gone by then, so the name is free again. There's no special "unstick" command for this particular state, and that's by design, not an oversight.
From the console: select the stack, choose Delete, confirm when prompted. The stack moves to DELETE_IN_PROGRESS and, once every resource it still owns is gone, to DELETE_COMPLETE. Deleted stacks disappear from the console's default view; if you want to look at one afterward, switch the stack status filter to include deleted stacks.
From the command line:
aws cloudformation delete-stack --stack-name your-stack-name
# Optional: block until it's actually gone before you script the next step
aws cloudformation wait stack-delete-complete --stack-name your-stack-name
Then recreate:
aws cloudformation create-stack \
--stack-name your-stack-name \
--template-body file://template.yaml \
--capabilities CAPABILITY_IAM CAPABILITY_NAMED_IAM
One genuinely important thing to remember about a ROLLBACK_COMPLETE stack: because it's the result of a failed creation, in the normal case there's nothing valuable actually left inside it to worry about losing. CloudFormation already deleted everything it created during that failed attempt as part of reaching this state. The exception, and it's a real one, is anything you told CloudFormation to keep on purpose — which is its own section below, because it changes how you should think about hardcoded names and data-bearing resources going forward.
✅ Why "just delete it" is genuinely the right call here
People sometimes resist deleting a failed stack because "delete" sounds destructive. For a stack stuck in ROLLBACK_COMPLETE, it isn't — the resources it would have contained are already gone. You're not deleting a working system; you're deleting an empty shell that AWS is still keeping a record of so it can refuse to let you update it. Clearing that shell is the fix, not a risk.
What if the delete itself won't finish
Occasionally the fix for the fix has its own problem: you try to delete the ROLLBACK_COMPLETE stack, and the delete itself fails, landing the stack in DELETE_FAILED. This isn't rare, and it isn't a dead end either, but it does mean one more resource is fighting you.
The most common reasons a delete fails:
- The resource has to be emptied first. S3 buckets with objects still in them, or EC2 security groups still attached to running instances, both refuse to delete until they're empty.
- You lack permission to delete it. Deleting a resource requires permission in that resource's own service, separate from CloudFormation permissions generally.
- Termination protection is turned on for the stack, which is a deliberate safeguard, not a bug — the delete simply won't proceed while it's enabled, and the stack's status stays exactly as it was.
- Another stack still depends on the resource, so deleting it out from under that dependency would break something else, and CloudFormation refuses on purpose.
Fix the specific blocker — empty the bucket, add the missing permission, disable termination protection, or resolve the cross-stack dependency — and retry the delete. If a particular resource genuinely can't be deleted and you're fine leaving it behind (an S3 bucket holding files you want to keep, for instance), you can retry the deletion while specifically retaining that resource, which lets CloudFormation delete the stack record itself while leaving that one resource orphaned but intact for you to manage by hand afterward. The console's "Retry delete" option on a DELETE_FAILED stack offers exactly this choice, letting you select individual resources to retain, or, if you'd rather stop fighting it resource by resource, a broader force-delete option that retains everything still refusing to go, along with anything depending on it.
🙋♂️ Jake's Reality Check
"What if I don't have permission to delete something in my own stack? Am I just stuck forever?"
If you genuinely don't have permission and there's nobody with more access, yes, you're stuck until someone grants it. This is one of the few honest "no" answers in CloudFormation. There's no workaround that lets a stack finish deleting a resource its caller isn't allowed to touch. Get the permission added, even temporarily, and the rest resolves itself.
Keeping data alive across a delete and recreate
This section matters most for people whose stack failed on attempt three or four, after earlier attempts already succeeded and started holding real data — a database with rows in it, an S3 bucket with uploaded files. If your very first creation attempt failed, there's genuinely nothing to preserve; nothing ever finished long enough to hold anything real. But if you're re-deploying a template that has failed and been recreated before, and one of the resources is something stateful, it's worth pausing here before you run delete-stack out of habit.
CloudFormation deletes every resource in a stack when the stack is deleted, unless a resource has an explicit DeletionPolicy attribute telling it to do something else. A DeletionPolicy of Retain tells CloudFormation to leave that specific resource behind, orphaned but intact, when the stack around it goes away. Setting this on anything genuinely stateful — a database, a bucket with data you can't regenerate — before you ever hit your first failure is cheap insurance. Setting it after the fact, on a template you're about to redeploy for the fourth time, is still worth doing if you haven't already.
⚠️ What actually gets destroyed if you skip this
Without a Retain deletion policy, deleting the stack deletes the database, the bucket, all of it, with the same finality as any other resource. There's no undo, no recycle bin, no thirty-day grace period on most resource types. If your stack has anything with real, irreplaceable data in it, confirm its deletion policy before you run delete-stack, not after.
Every way CloudFormation lets you control what happens on failure
Here's the fact most people never discover until after their first rough night with this exact problem: the all-or-nothing default isn't the only option, and it isn't even the only kind of option. CloudFormation actually gives you three separate, slightly different levers, and it's worth knowing all three exist so you pick the right one instead of stumbling onto whichever one a blog post happened to mention.
The console's Stack failure options
On the Configure stack options page when you create a stack, there's a setting called stack failure options, and its default choice is Roll back all stack resources — exactly the all-or-nothing behavior described earlier. The other choice, Preserve successfully provisioned resources, changes it: on a failed creation, the resources that succeeded are left standing, and only the resources that failed stay in a failed state, ready to be fixed on your very next update instead of demolished and rebuilt from scratch. On updates and change sets, this same option preserves the successful resources while rolling back the failed ones to their last known stable state, with resources that have no prior stable state getting deleted on the next stack operation instead of immediately.
The API-level OnFailure parameter
If you're calling CreateStack directly, or through the CLI's create-stack command, there's a separate, lower-level parameter called OnFailure, and it isn't the same lever as the console option above — it controls a different axis of behavior entirely. Its default is ROLLBACK, matching everything described so far. Set it to DELETE and, instead of leaving a dead ROLLBACK_COMPLETE stack sitting in your account for you to clean up, CloudFormation automatically deletes the whole failed stack for you the moment creation fails — useful for automated pipelines where a human isn't going to be there to run delete-stack by hand. Set it to DO_NOTHING and CloudFormation leaves the partially-created resources exactly as they failed, untouched, which is genuinely useful while you're actively debugging a new template and want to inspect what actually got built before anything gets cleaned up.
There's one exception worth knowing: when a StackSet deploys a stack instance and that instance fails to create, the underlying CreateStack call overrides the normal ROLLBACK default and sets OnFailure to DELETE automatically, regardless of what you specified elsewhere. There's also a closely related, older boolean flag, DisableRollback, which simply turns rollback off on stack creation without the DELETE/DO_NOTHING distinction — you can specify one or the other, never both.
| Lever | What it actually controls | Set it via |
|---|---|---|
| Stack failure options (console) | Whether successful resources survive a failure alongside the failed ones | Configure stack options page |
OnFailure | Whether a failed creation rolls back, deletes itself, or is left untouched | CreateStack API / CLI --on-failure |
DisableRollback | Simple on/off switch for rollback on creation failure only | CreateStack API / CLI --disable-rollback |
✅ Which one to actually reach for
For a production stack with expensive or slow-to-recreate resources, turn on Preserve successfully provisioned resources so one bad property value doesn't cost you a half-hour RDS provision you already paid for once. For debugging a brand-new template interactively, DisableRollback or OnFailure=DO_NOTHING is more useful, since it leaves the broken resource sitting there for you to inspect instead of vanishing before you can see what actually happened. For an automated pipeline nobody's watching, OnFailure=DELETE means a failed first deployment cleans itself up instead of leaving a dead stack for the next run to trip over.
Automating the cleanup so a pipeline never gets stuck on it
If you're deploying CloudFormation through a CI/CD pipeline rather than a person clicking buttons, a ROLLBACK_COMPLETE stack blocking the next deployment is worse than an annoyance — it's a build that fails for a reason nobody on the team is watching for. If you use AWS CodePipeline with CloudFormation as a deploy action, there's a specific action mode built for exactly this: setting the pipeline's CloudFormation action to replace a failed stack instead of the standard create-or-update mode. With that mode set, if the target stack exists and is in a failed state — documented as covering ROLLBACK_COMPLETE, ROLLBACK_FAILED, CREATE_FAILED, DELETE_FAILED, or UPDATE_ROLLBACK_FAILED — CloudFormation deletes it and creates a fresh one automatically. If the stack isn't in a failed state, it updates normally, same as always. Reach for this mode when you specifically want to replace failed stacks without recovering or troubleshooting them, which fits testing environments better than production ones you actually want to inspect before nuking.
Outside CodePipeline specifically, the same idea works with plain CloudFormation as long as you control how the stack gets created in the first place: setting OnFailure=DELETE on the initial create-stack call, as covered above, means a fresh pipeline run that fails on first deployment cleans up after itself instead of leaving a dead stack sitting there for the next run to collide with. Either approach turns "someone has to notice the stuck stack and manually delete it" into "the pipeline already handled it," which matters a lot more once more than one person on a team is deploying the same infrastructure.
🙋♂️ Jake's Reality Check
"I'm one guy running a phone shop, not a whole engineering team. Do I actually need any of this pipeline stuff?"
Honestly, probably not yet. Ethan's blunt about this one: automation like this earns its keep once more than one person deploys the same stack, or once you're deploying often enough that a stuck stack becomes a recurring interruption rather than a once-a-quarter surprise. For a one-person shop redeploying occasionally, knowing the manual delete-and-recreate steps cold is worth more than wiring up a pipeline you'll rarely touch.
CDK and SAM users hit this exact same wall
If you're deploying through the AWS CDK or SAM CLI rather than raw CloudFormation templates, none of the above changes — both tools are just generating a CloudFormation template behind the scenes and calling the same create-stack and update-stack APIs. A cdk deploy or sam deploy that fails on first launch leaves you looking at exactly the same ROLLBACK_COMPLETE stack underneath, and both tools will refuse to update it for the same reason CloudFormation itself does.
The CDK's CLI is upfront about this: when it detects the target stack is in ROLLBACK_COMPLETE, the answer is to delete the stack first. For SAM, sam deploy exposes an --on-failure option you can set for future deployments — ROLLBACK (the default, matching plain CloudFormation), DELETE (which automatically deletes a stack that fails to create instead of leaving it stuck for you to clean up manually), or DO_NOTHING (which leaves the partially-created resources in place for you to inspect, useful while you're actively debugging a new template but not something you want left on by default). Setting --on-failure DELETE on a development-stage stack you redeploy often removes this entire class of "why won't it update" question before it happens, at the cost of losing that half-built state to inspect after a failure.
One CDK-specific case worth calling out separately: the CDK's own bootstrap stack, usually named CDKToolkit, is itself a CloudFormation stack, and it can land in exactly this same state if the identity running cdk bootstrap doesn't have sufficient permissions, or if a staging bucket the bootstrap expects to create already exists from an earlier partial attempt. The fix is identical to everything above: read the actual events for that CDKToolkit stack, fix the permission or naming conflict, delete it, and bootstrap again.
Termination protection, StackSets, and other things that get in the way
A handful of other account-level settings can complicate the delete step specifically, even once you've correctly diagnosed the root cause.
Termination protection is designed to stop accidental deletes of important stacks, and it does exactly that — a delete attempt against a protected stack fails outright, and the stack, including its status, stays untouched. If you enabled this on a stack that later failed creation and landed in ROLLBACK_COMPLETE, you have to explicitly disable termination protection before the delete will go through. For nested stacks, this protection is inherited from whichever root stack has it enabled; you disable it on the root, not on the individual nested stack, and it's genuinely bad practice to delete nested stacks directly rather than as part of deleting the whole root stack anyway.
AWS Config and Systems Manager automations running in the same account can occasionally step on a CloudFormation deployment mid-flight, modifying or reverting something CloudFormation is actively trying to create, which produces failures that look like a plain CloudFormation bug but actually trace back to an unrelated automation rule. If your failures seem to come and go without any change to your template, it's worth checking whether either of those services has active rules touching the same resource types.
StackSets deployments — where one template is deployed across many accounts and Regions at once — behave the same way at the individual stack instance level: a stack instance whose creation fails in a given account and Region can land in the same ROLLBACK_COMPLETE-style failure independently of the others, and you troubleshoot that one instance exactly like a standalone stack, by opening its own events in that specific account and Region. Remember the exception mentioned earlier, too: StackSets override the normal ROLLBACK default and set failed stack instances to delete themselves automatically, so you may not even see a lingering ROLLBACK_COMPLETE stack to clean up in that specific case — it's already gone by the time you go looking.
Before you paste your error into a forum or a support ticket
Once you've found the actual status reason, the natural next move if it still doesn't make sense is to paste it somewhere for a second opinion — a forum, a coworker in Slack, an AWS Support case. Before you do, it's worth a quick pass over what you're about to share. Status reasons and stack events routinely include your full account ID, resource ARNs, IAM role and policy names, and, occasionally, parameter values you passed in yourself — database names, internal hostnames, anything that isn't secret-manager-protected but also isn't something you'd want sitting in a public forum post indefinitely. None of that is sensitive in the way a password is, but an account ID and a resource ARN together tell a stranger more about your account's shape than most people realize when they're in a hurry to get an answer. If AWS Support is the route you're taking, they'll ask for the stack ID specifically, which you can find on the stack's Overview tab — that's the identifier worth handing over, rather than a full copy-paste of the raw events log with everything else still attached to it.
🙋♂️ Jake's Reality Check
"I almost posted a screenshot of the whole Events tab in a Facebook group for help. Was that actually a problem?"
Probably not a disaster, but not a great habit either. Ethan's rule of thumb: crop it down to the one row with the actual error before you share it anywhere public. You lose nothing useful by trimming out your account ID and every resource ARN that isn't the one causing the problem, and you avoid handing a stranger a map of your account for no benefit to either of you.
💡 A small win Jake didn't expect: once he'd found the real error — that hardcoded S3 bucket name his freelancer had picked, already claimed by someone else on the internet — the whole fix took less time than the panic did. He removed the hardcoded name, deleted the dead stack, redeployed, and had his ticket app back up an hour before close. Ethan's closing line to him, half-joking: "You just spent forty-five minutes scared of three words: 'already exists.' Write that down somewhere so next time it's five minutes." The lesson that stuck with Jake wasn't the bucket name. It was that the scary red status and the actual fix are almost never the same size.
Frequently asked questions
What does CloudFormation ROLLBACK_COMPLETE actually mean?
It means the stack's first creation attempt failed on at least one resource, and CloudFormation successfully deleted every resource it had already managed to create as part of cleaning up. The stack itself still exists as a record, in a terminal, un-updatable state.
Why can't I just update a stack that's in ROLLBACK_COMPLETE?
Because CloudFormation only knows how to update a stack that reached a stable, complete state at least once. A stack that never finished creating has no known-good baseline to update from, so the API refuses the request rather than guess.
Is ROLLBACK_COMPLETE the same as UPDATE_ROLLBACK_FAILED?
No. ROLLBACK_COMPLETE comes from a failed stack creation that finished rolling back cleanly. UPDATE_ROLLBACK_FAILED comes from an existing, previously working stack whose update failed and whose rollback also failed. The continue-update-rollback fix applies only to the second case.
Does deleting a ROLLBACK_COMPLETE stack delete my data too?
Usually there's no data left to lose, because CloudFormation already deleted everything the failed attempt created. The exception is anything explicitly marked with a Retain deletion policy, or anything that survived from an earlier successful attempt at the same stack before a later attempt failed.
How do I find out which resource actually caused the rollback?
Open the stack's Events tab and scroll to the earliest row with a CREATE_FAILED status, then read its Status reason. From the CLI, describe-stack-events with a query filtered to CREATE_FAILED gives you the same answer in one command.
What's the single most common cause of ROLLBACK_COMPLETE?
Insufficient IAM permissions on whichever identity is creating the stack. The status reason usually names the exact action and resource that was denied.
Can I skip the failed resource and keep the rest of the stack?
Not on the failed attempt itself, unless the stack failure option was already set to Preserve successfully provisioned resources before deployment. Without that setting active in advance, the default deletes every resource once one fails.
What happens if the delete itself fails?
The stack moves to DELETE_FAILED instead of DELETE_COMPLETE. Common causes are a resource that has to be emptied first, missing delete permissions, termination protection, or another stack depending on the same resource. Fix the blocker and retry, or retain the stuck resource and force the deletion through.
Can I retain specific resources when I delete the stack?
Yes. Retrying a failed deletion with a resource marked to retain lets CloudFormation delete the stack record while leaving that resource behind, orphaned but intact, for manual management afterward.
Does this happen with SAM and CDK too?
Yes. Both deploy through the same CloudFormation APIs, so a failed first deployment lands in the identical ROLLBACK_COMPLETE state. SAM's deploy command offers an on-failure option to auto-delete a failed stack; CDK's CLI tells you directly to delete the stack when it detects this state.
Why did my stack roll back even though only one resource out of ten failed?
The default stack failure setting rolls back all stack resources on any failure, not just the one that broke. That all-or-nothing guarantee applies to every resource in the template regardless of how many others succeeded.
Can I stop CloudFormation from rolling back everything next time?
Yes, by choosing Preserve successfully provisioned resources instead of the default Roll back all stack resources on the Configure stack options page, or by setting OnFailure to DO_NOTHING or DELETE at the API level depending on what you want to happen instead. None of these prevent the underlying error, but they change what a failure actually costs you.
What if the stack is a nested stack — where do I even look?
Find the failed resource in the parent whose type is AWS::CloudFormation::Stack, then open that resource's own physical stack ID as a separate stack and read its events. The parent's own event usually only says the nested stack failed, without the real underlying reason.
Is there a way to catch this before it ever happens?
Yes, in layers. Validating the template with validate-template catches syntax and structure errors for free before anything is created. CloudFormation's own pre-deployment validation then catches property errors, resource name conflicts, and quota warnings before provisioning starts. For deployments after the first one, creating a change set before executing it shows exactly what will change, catching most of what would otherwise trigger a failed update.
What is the difference between ROLLBACK_COMPLETE and UPDATE_ROLLBACK_COMPLETE?
ROLLBACK_COMPLETE follows a failed first creation: nothing usable is left and the stack can only be deleted. UPDATE_ROLLBACK_COMPLETE follows a failed update: CloudFormation restored the previous working version, and the stack is healthy and can be updated again normally.
Can I reuse the same stack name after deleting a ROLLBACK_COMPLETE stack?
Yes. Once the delete finishes and the stack shows DELETE_COMPLETE, the name is free, and you can create a new stack with the same name straight away, after fixing whatever caused the first failure.
Revision note. Written September 2026, covering current CloudFormation stack behavior including the stack failure options available for create and update operations, and the OnFailure and DisableRollback parameters at the API level. AWS occasionally adds new recovery options to the console faster than any article can track, so if a newer built-in fix exists by the time you're reading this, the console's own Stack actions menu is the fastest way to confirm it. If you're staring at a red ROLLBACK_COMPLETE banner right now with a deadline behind it, take a breath — the fix underneath it is almost always smaller than the status makes it feel.