Skip to content

Fix: AWS CloudFormation stack in ROLLBACK_COMPLETE or CREATE_FAILED state

FixDevs ·

Quick Answer

How to fix AWS CloudFormation ROLLBACK_COMPLETE and CREATE_FAILED errors caused by IAM permissions, resource limits, invalid parameters, and dependency failures.

The Error

Your CloudFormation stack creation fails and enters:

Status: ROLLBACK_COMPLETE
Status reason: The following resource(s) failed to create: [MyEC2Instance, MySecurityGroup].

Or variations:

CREATE_FAILED - Resource handler returned message: "Access Denied (Service: S3, Status Code: 403)"
ROLLBACK_IN_PROGRESS - The following resource(s) failed to create: [MyLambdaFunction].
Rollback requested by user.
UPDATE_ROLLBACK_COMPLETE - Parameter validation failed
DELETE_FAILED - Cannot delete stack: it has nested stacks that are in DELETE_FAILED state

CloudFormation tried to create or update resources, one or more failed, and the stack rolled back to its previous state (or failed entirely for new stacks). A stack in ROLLBACK_COMPLETE cannot be updated — it must be deleted and recreated.

Why This Happens

CloudFormation creates resources in dependency order. When a resource creation fails, CloudFormation rolls back by deleting the resources it already created. If the entire stack was new, it ends in ROLLBACK_COMPLETE.

Common causes:

  • IAM permissions. The CloudFormation role does not have permission to create the resources.
  • Resource limits. AWS account limits (VPCs, Elastic IPs, etc.) are exceeded.
  • Invalid parameters. Wrong AMI ID, non-existent subnet, or invalid instance type.
  • Name conflicts. A resource with the same name already exists.
  • Dependency failures. A resource that another depends on failed to create.
  • Template errors. Invalid YAML/JSON, missing required properties, or wrong resource types.

Fix 1: Find the Root Cause in Events

Always check the stack events first:

aws cloudformation describe-stack-events \
    --stack-name my-stack \
    --query "StackEvents[?ResourceStatus=='CREATE_FAILED'].[LogicalResourceId,ResourceStatusReason]" \
    --output table

In the AWS Console: CloudFormation → Your Stack → Events tab. Look for the first CREATE_FAILED event — that is the root cause. Subsequent failures are usually cascading.

Common error messages and fixes:

ErrorCauseFix
Access DeniedMissing IAM permissionsAdd permissions to the CloudFormation role
Limit ExceededAWS service quota reachedRequest a quota increase
Resource already existsName conflictUse unique names or import existing resources
Parameter validation failedInvalid template parameterFix the parameter value
Template format errorInvalid YAML/JSONValidate the template

Pro Tip: The first CREATE_FAILED event in the timeline is the root cause. All other failures after that are typically cascading failures caused by the first one. Fix the first error, and the rest usually resolve.

Fix 2: Delete ROLLBACK_COMPLETE Stacks

A stack in ROLLBACK_COMPLETE cannot be updated. You must delete and recreate it:

# Delete the failed stack
aws cloudformation delete-stack --stack-name my-stack

# Wait for deletion
aws cloudformation wait stack-delete-complete --stack-name my-stack

# Recreate
aws cloudformation create-stack \
    --stack-name my-stack \
    --template-body file://template.yaml \
    --parameters file://params.json \
    --capabilities CAPABILITY_NAMED_IAM

If delete fails (resources cannot be cleaned up):

# Skip specific resources during deletion
aws cloudformation delete-stack \
    --stack-name my-stack \
    --retain-resources MyRDSInstance MyS3Bucket

This deletes the stack but leaves the specified resources in place. Clean them up manually later.

Fix 3: Fix IAM Permission Errors

CloudFormation needs permissions to create every resource in the template:

Add permissions to the CloudFormation role:

{
    "Version": "2012-10-17",
    "Statement": [
        {
            "Effect": "Allow",
            "Action": [
                "ec2:*",
                "s3:*",
                "lambda:*",
                "iam:*",
                "logs:*"
            ],
            "Resource": "*"
        }
    ]
}

For least privilege (recommended):

{
    "Effect": "Allow",
    "Action": [
        "ec2:CreateSecurityGroup",
        "ec2:AuthorizeSecurityGroupIngress",
        "ec2:RunInstances",
        "ec2:DescribeInstances",
        "ec2:TerminateInstances"
    ],
    "Resource": "*"
}

Pass a role to CloudFormation:

aws cloudformation create-stack \
    --stack-name my-stack \
    --template-body file://template.yaml \
    --role-arn arn:aws:iam::123456789012:role/CloudFormationRole \
    --capabilities CAPABILITY_NAMED_IAM

Required capabilities for IAM resources:

# For IAM resources with custom names
--capabilities CAPABILITY_NAMED_IAM

# For IAM resources without custom names
--capabilities CAPABILITY_IAM

# For nested stacks with transforms
--capabilities CAPABILITY_AUTO_EXPAND

Common Mistake: Forgetting --capabilities CAPABILITY_NAMED_IAM. CloudFormation refuses to create IAM resources without explicit acknowledgment. This causes an error before any resources are created.

Fix 4: Validate the Template Before Deploying

Catch errors before they cause a rollback:

# Validate template syntax
aws cloudformation validate-template --template-body file://template.yaml

# Create a change set (dry run)
aws cloudformation create-change-set \
    --stack-name my-stack \
    --template-body file://template.yaml \
    --change-set-name preview \
    --parameters file://params.json

# Review the change set
aws cloudformation describe-change-set \
    --stack-name my-stack \
    --change-set-name preview

Use cfn-lint for deeper validation:

pip install cfn-lint
cfn-lint template.yaml

Common template errors:

# Wrong — missing required property
Resources:
  MyBucket:
    Type: AWS::S3::Bucket
    Properties: {}  # BucketName is optional, but other resources have required props

# Wrong — wrong property type
Resources:
  MyInstance:
    Type: AWS::EC2::Instance
    Properties:
      InstanceType: "t2.micro"
      SubnetId: "subnet-12345"  # Must be a valid subnet ID in your VPC
      ImageId: "ami-12345"      # Must be a valid AMI in your region

# Wrong — referencing non-existent resource
Resources:
  MyInstance:
    Type: AWS::EC2::Instance
    Properties:
      SecurityGroupIds:
        - !Ref NonExistentSG  # This resource doesn't exist in the template

Fix 5: Fix Resource Limit Errors

AWS has default limits on many resources:

# Check your current limits
aws service-quotas list-service-quotas --service-code ec2

# Request an increase
aws service-quotas request-service-quota-increase \
    --service-code ec2 \
    --quota-code L-1216C47A \
    --desired-value 10

Common limits:

ResourceDefault Limit
VPCs per region5
Elastic IPs5
EC2 instances (on-demand)varies by type
S3 buckets100
Lambda concurrent executions1000
CloudFormation stacks200

Fix 6: Fix Disable Rollback for Debugging

Disable rollback to keep failed resources for inspection:

aws cloudformation create-stack \
    --stack-name my-stack \
    --template-body file://template.yaml \
    --disable-rollback

With rollback disabled, the stack stays in CREATE_FAILED state with the successfully created resources still running. You can inspect them to understand the failure.

Delete when done debugging:

aws cloudformation delete-stack --stack-name my-stack

Fix 7: Fix Circular Dependencies

CloudFormation cannot resolve circular references:

Broken:

Resources:
  SecurityGroup:
    Type: AWS::EC2::SecurityGroup
    Properties:
      SecurityGroupIngress:
        - SourceSecurityGroupId: !Ref SecurityGroup  # References itself!

Fixed — use a separate ingress rule:

Resources:
  SecurityGroup:
    Type: AWS::EC2::SecurityGroup
    Properties:
      GroupDescription: My SG

  IngressRule:
    Type: AWS::EC2::SecurityGroupIngress
    Properties:
      GroupId: !Ref SecurityGroup
      SourceSecurityGroupId: !Ref SecurityGroup
      IpProtocol: tcp
      FromPort: 443
      ToPort: 443

Fix 8: Fix UPDATE_ROLLBACK_FAILED

The worst state — the stack cannot complete its rollback:

# Continue the rollback, skipping problematic resources
aws cloudformation continue-update-rollback \
    --stack-name my-stack \
    --resources-to-skip MyLambdaFunction MyCustomResource

This tells CloudFormation to skip the resources that cannot be rolled back and finish the rollback process. After this, you can attempt the update again or delete the stack.

Still Not Working?

Check CloudTrail for detailed API errors:

aws cloudtrail lookup-events \
    --lookup-attributes AttributeKey=ResourceName,AttributeValue=my-stack \
    --max-items 10

Check for nested stack failures. If your template uses nested stacks, check the events of the nested stack for the actual error.

Check for custom resource failures. Lambda-backed custom resources might fail silently. Check the Lambda function logs:

aws logs filter-log-events \
    --log-group-name /aws/lambda/my-custom-resource \
    --start-time $(date -d '1 hour ago' +%s000)

Use aws cloudformation describe-stack-resources to see which resources were created before the failure.

For AWS IAM permission errors, see Fix: AWS IAM AccessDeniedException. For S3 access issues, see Fix: AWS S3 Access Denied. For Lambda timeout issues, see Fix: AWS Lambda timeout.

F

FixDevs

Solo developer based in Japan. Every solution is cross-referenced with official documentation and tested before publishing.

Was this article helpful?

Related Articles