---
cuppy_hub: aws
cuppy_path: reference/cloudformation/errors.md
cuppy_section: docs
cuppy_doc: Y44G-Q97X
cuppy_doc_uuid: f048dd0f-d62d-4b0a-ab9d-76e7ff490443
cuppy_permalink: https://cuppy.io/aws/d/Y44G-Q97X
cuppy_version: 4
cuppy_updated: 2026-10-23T16:16:52.575Z
cuppy_canonical: https://cuppy.io/aws/docs/reference/cloudformation/errors
cuppy_mcp: https://cuppy.io/mcp
cuppy_body_sha256: c9c199e51f6b4664412eff308398b4129dfbfbebff4d5f6dfbdb1307c6a16b7a
# cuppy_body_sha256 is over the document body ALONE, excluding both generated blocks.
---


# AWS CloudFormation errors

**There are two places to look.** A call that is refused outright (bad template, missing capability, name taken) fails with an API exception and creates or changes nothing. A call that is accepted but fails while running shows the error in **stack events**, as a resource's `ResourceStatusReason`. Find the first failed event first (`guides/cloudformation/fix-failed-stack.md`).

## API exceptions (HTTP 400)

The SDK class names end in `Exception`; the API reference lists the bare names.

| Exception | Cause → fix | Check |
|---|---|---|
| `InsufficientCapabilitiesException` | The template has resources that need a capability you didn't pass. IAM resources (`AccessKey`, `Group`, `InstanceProfile`, `ManagedPolicy`, `Policy`, `Role`, `User`, `UserToGroupAddition`) need `CAPABILITY_IAM`, or `CAPABILITY_NAMED_IAM` if any have custom names. Macros, including `AWS::Serverless` and `AWS::Include`, need `CAPABILITY_AUTO_EXPAND` when you create the stack directly rather than through a change set | `aws cloudformation get-template-summary --template-body file://t.yaml --query Capabilities` |
| `AlreadyExistsException` | A stack with that name exists. Update it or rename | `aws cloudformation describe-stacks --stack-name <s>` |
| `LimitExceededException` | A CloudFormation quota is reached (`reference/cloudformation/stack-operations.md` lists which ones are adjustable) | Service Quotas for CloudFormation; `aws cloudformation list-stacks` count |
| `TokenAlreadyExistsException` | "A client request token already exists." Use a fresh `ClientRequestToken` for each new operation | `aws cloudformation describe-stacks --stack-name <s>` |
| `ChangeSetNotFoundException` | Wrong change set name or ARN, or it was deleted. Executing one change set **deletes all the others** for that stack | `aws cloudformation list-change-sets --stack-name <s>` |
| `InvalidChangeSetStatusException` | The change set's status doesn't allow the call: read `Status`, `ExecutionStatus`, `StatusReason` | `aws cloudformation describe-change-set --stack-name <s> --change-set-name <c>` |
| `OperationInProgressException`, `StackNotFoundException`, `StaleRequestException`, `CreatedButModifiedException` | Causes not described on the fetched pages: read the message | The message; `describe-stacks` → `StackStatus` |

## `ValidationError` messages (not a modelled exception: match on the message)

| Message | Cause → fix | Check |
|---|---|---|
| `No updates are to be performed.` | No template or parameter change. `DeletionPolicy`, `UpdatePolicy`, `Conditions` or `Outputs` alone don't count: also change a resource's `Metadata`. Treat as success in scripts | Diff `aws cloudformation get-template --stack-name <s>` with your template |
| `The submitted information didn't contain changes.` | A change set came out with nothing to do, so its status is `FAILED` with this reason. Delete it and move on (the CDK reports "(no changes)") | `describe-change-set` → `StatusReason` |
| `Stack with id <name> does not exist` | Wrong name or Region, or the stack was deleted. A `ROLLBACK_COMPLETE` stack still exists: delete it first | `aws cloudformation list-stacks --region <r>` (deleted stacks show `DELETE_COMPLETE`) |
| Stack in `ROLLBACK_COMPLETE` / `UPDATE_ROLLBACK_FAILED` / `DELETE_FAILED` refused for update | That status doesn't allow updates. Follow the move for that status in `guides/cloudformation/fix-failed-stack.md` | `describe-stacks --stack-name <s> --query 'Stacks[0].StackStatus'` |

## Resource status reasons in stack events

**Check for every row:** `aws cloudformation describe-stack-events --stack-name <s> --query "StackEvents[?ends_with(ResourceStatus,'FAILED')].[Timestamp,LogicalResourceId,ResourceType,ResourceStatusReason]"`. Events are newest first, so the **last** line is the first failure: match its reason below.

| Reason (verbatim where quoted) | Cause → fix |
|---|---|
| `<name> already exists` (for example `CREATE_FAILED \| AWS::S3::Bucket \| <BucketName> already exists`) | A hard-coded physical name is already taken: S3 bucket names are global in the partition, and IAM, Route 53 zones and CloudFront are not Regional. Let CloudFormation generate names, delete the leftover (often one **retained** from an earlier stack), or import it (`reference/cloudformation/change-sets-drift-and-import.md`) |
| Resource **failed to stabilize** | The operation outlived CloudFormation's wait, or the service was impaired. Slow types: Auto Scaling groups, ACM certificates (create), nested stacks, OpenSearch/Elasticsearch domains (update), RDS clusters and instances, and Redshift (update). Check service health, then run the operation with a **service role** (`RoleARN`), which allows a longer timeout. For ACM, validation must complete (`reference/acm/certificates.md`) |
| Wait condition or creation policy **didn't receive the required number of signals** | The instance never ran `cfn-signal`. Check that the helper scripts are in the AMI, that `cfn-signal` ran (`/var/log/cfn-init.log`, `/var/log/cloud-init.log`), and that there is a route out (NAT or internet gateway; `curl -I https://aws.amazon.com` should return 200). Disable rollback to keep the instance for inspection |
| `Status=start_failed` (EC2) | A service quota, such as On-Demand instances, was reached. **Replacements** create the new resource before deleting the old one, so they can cross a quota during updates. Raise the quota or remove spares |
| Security group **does not exist in VPC** | You passed a group *name* where a VPC needs an *ID*. Use `SourceSecurityGroupId` (not `SourceSecurityGroupName`), and check the group is in that VPC |
| Invalid value or unsupported property | A parameter references something that doesn't exist in this account and Region (key pair, VPC ID), or a property name or value is wrong. Use AWS-specific parameter types so bad values fail early |
| Access denied from an underlying service | The caller, or the stack's service role, lacks permissions for the **service** (S3, EC2, …), not just CloudFormation. Use `reference/iam/errors.md` to read which policy refused |
| `UPDATE_COMPLETE` whose `StatusReason` says resources couldn't be deleted, plus a `DELETE_FAILED` event for one | After three failed delete attempts, CloudFormation dropped the old resource from the stack but left it in your account. Delete it through its own service |
| `DependsOn` ordering failures (for example, an EIP created before the internet gateway is attached) | Add `DependsOn` |
| Conflicts with AWS Config rules or Systems Manager automations | An automation changed or locked a resource mid-deploy. Pause it for the deployment |

## Custom resources

A custom resource must PUT its response to the presigned S3 URL. If none arrives, the operation waits up to **`ServiceTimeout`**: 1–3600 seconds, default 3600, a full hour. Then the operation fails. Set `ServiceTimeout` low while developing, and always respond, including on errors and on `Delete`. Returning a **different `PhysicalResourceId`** on update is treated as a replacement, and CloudFormation then sends `Delete` for the old ID.

## Pre-deployment validation (at create or change-set time)

| Finding | Fix | Check |
|---|---|---|
| Property syntax validation failed | Read `ValidationStatusReason` on the event: it gives the **property path**. Fix the type, enum, ARN pattern or missing required property | `aws cloudformation describe-events --change-set-name <c-arn>` → `ValidationStatusReason`, `ValidationPath` |
| Resource name conflict | The named resource already exists and that type can't adopt it. Rename it, or remove the existing one | Same call → `ValidationName`, `ValidationStatus` |
| Service quota warning | The deployment would exceed a quota. Request an increase | Same call; Service Quotas for the named service |

On change sets these checks only **warn**, and they also cover Config recorder conflicts and whether ECR repositories can be deleted. If you're sure a finding is a false positive, bypass it with `--disable-validation` (`DisableValidation: true`).

## Cross-stack references

- **Exports:** while another stack imports an export, you can't delete the exporting stack or change the exported value. The exact error text wasn't on the fetched pages. Find the importers with `aws cloudformation list-imports --export-name <name>` and remove those imports first. The CDK version of this lock is in `guides/cdk/write-stacks-in-typescript.md`.
- **`Fn::GetStackOutput`** returns **`InternalFailure`** when it is placed inside an `Fn::Sub` variable map, inside `Fn::Base64`, directly as an `Outputs` value, in `Fn::Equals` under `Conditions`, or inside `Fn::ImportValue`. Move it to a resource property or into `Fn::Join`, `Fn::If` or `Fn::Select`.

## Passing lists on the CLI

`Error parsing parameter` when passing a list: escape the commas inside the value, for example `ParameterKey=CIDR,ParameterValue='10.10.0.0/16\,10.10.0.0/24'`.

## When none of these fits

Find the **first** failed event (`guides/cloudformation/fix-failed-stack.md`) and search the hub for its `ResourceStatusReason`. The text there usually comes from the underlying service, so that service's errors document under `reference/` applies. If the reason names no service error, look up that resource type's create/update call in CloudTrail at the event's time (`guides/cloudtrail/find-who-did-what.md`). Keep the stack ID and event IDs for AWS Support.


---
<!-- cuppy -->
You are reading one file. The same content is free over MCP at https://cuppy.io/mcp with no signup: ranked search across all 131 documents in this hub, the merged view when you work in a layer, known workarounds matched to the error you hit, and depth control so you spend tokens on what you need. Start with the `_hello` tool. How to connect: https://cuppy.io/aws/ Something wrong in this document? Report it with the `session feedback` tool on the same endpoint.
<!-- /cuppy -->
