---
cuppy_hub: aws
cuppy_path: reference/ec2/errors.md
cuppy_section: docs
cuppy_doc: 1ATC-M3EP
cuppy_doc_uuid: 7b262f50-bece-4e3e-9161-63f70a426a65
cuppy_permalink: https://cuppy.io/aws/d/1ATC-M3EP
cuppy_version: 4
cuppy_updated: 2026-10-23T16:16:52.575Z
cuppy_canonical: https://cuppy.io/aws/docs/reference/ec2/errors
cuppy_mcp: https://cuppy.io/mcp
cuppy_body_sha256: f369ee184f21c180b3e4df923105d62535f063f790ce4cf28d1999d3a2b2161c
# cuppy_body_sha256 is over the document body ALONE, excluding both generated blocks.
---


# Amazon EC2 API errors

**EC2 errors have a stable code (`UnauthorizedOperation`, `InvalidAMIID.NotFound`, …). Search by the code.** Two EC2 habits change how you read them. Authorization failures hide their detail in an **encoded message** you must decode. And the API is **eventually consistent**: a resource you just created can be "not found" for a short while.

## Authorization

### `UnauthorizedOperation`

```
An error occurred (UnauthorizedOperation) when calling the RunInstances operation: You are not authorized to perform this operation. Encoded authorization failure message: <long string>
```

Decode the message:

```
aws sts decode-authorization-message --encoded-message '<long string>' \
  --query DecodedMessage --output text | jq .
```

- The caller of `decode-authorization-message` needs **`sts:DecodeAuthorizationMessage`**. That permission is separate because the decoded message can reveal details of the policies involved.
- The decoded JSON says whether access was allowed, the explicit deny if there was one, the denied action, the resource, and the request context (tags, Region, principal).
- On `RunInstances`, a frequent cause is **`iam:PassRole`** on the instance profile's role, not an EC2 action. Other common causes: a tag-on-create condition (`ec2:CreateTags` with `aws:RequestTag`), a KMS key for encrypted volumes, or an SCP denying the Region or instance type.

Not every EC2 failure is encoded. `AuthFailure` concerns the credentials themselves: invalid or expired keys, or a bad signature (UNVERIFIED description in the collected sources). For the general method, see `guides/iam/fix-access-denied.md`.

## Capacity and quotas

| Code | Cause → fix | Check |
|---|---|---|
| `InsufficientInstanceCapacity` | AWS does not currently have enough capacity of that instance type in that Availability Zone. Not your quota. Retry later, use another AZ (another subnet), or another instance type. Spread launches across AZs and types | The same launch in another subnet's AZ succeeds |
| `VcpuLimitExceeded` | The account's **vCPU-based** quota for that instance family (On-Demand or Spot) would be exceeded. Request an increase in Service Quotas, or stop or terminate instances | `aws service-quotas list-service-quotas --service-code ec2` → the family's vCPU quota; sum the vCPUs running |
| `InstanceLimitExceeded` | An instance-count quota would be exceeded (older count-based limits). Same remedy | Same call |
| `RequestLimitExceeded` | The API throttled your request rate. Retry with exponential backoff and jitter. The SDKs retry automatically. Reduce polling; use `wait` commands or EventBridge events | Calls per second in your code; SDK retry logs |

## Not found

| Code | Cause → fix | Check |
|---|---|---|
| `InvalidAMIID.NotFound` | The AMI ID is from another Region, deregistered, or not shared with you. **Or** the account's **Allowed AMIs** setting excludes it, in which case the AMI exists but is reported as not found. Prefer `resolve:ssm:` parameters (`guides/ec2/launch-instance.md`) | `aws ec2 describe-images --image-ids <ami> --region <r>`; `aws ec2 get-allowed-images-settings` |
| `InvalidAMIID.Malformed` | Not a valid `ami-…` ID (UNVERIFIED code in the collected sources) | The ID's shape: `ami-` plus hex |
| `InvalidGroup.NotFound` | Security group in another VPC or Region, deleted, or **just created and not yet propagated** | `aws ec2 describe-security-groups --group-ids <sg> --query 'SecurityGroups[0].VpcId'` |
| `InvalidInstanceID.NotFound` | Wrong Region, terminated long ago, or **just launched**. `DescribeInstances` right after `RunInstances` can miss it | `--region` of the call; retry after a few seconds or use `aws ec2 wait instance-exists` |
| `InvalidSubnetID.NotFound`, `InvalidVpcID.NotFound` | Wrong Region or ID (UNVERIFIED codes in the collected sources) | `aws ec2 describe-subnets --subnet-ids <s> --region <r>` |

### Eventual consistency

EC2 API changes propagate over a short period. After creating something, retry dependent calls with backoff instead of failing on the first `…NotFound`. Use `aws ec2 wait instance-exists`, `instance-running` or `instance-status-ok` rather than a fixed sleep.

## Request problems

| Code | Cause → fix | Check |
|---|---|---|
| `InvalidParameterValue` / `InvalidParameterCombination` | Mutually exclusive or invalid options: for example an instance type that the AMI's architecture does not support, or a subnet and security group in different VPCs (UNVERIFIED examples) | `aws ec2 describe-images --image-ids <ami> --query 'Images[0].Architecture'` vs `aws ec2 describe-instance-types --instance-types <t> --query 'InstanceTypes[0].ProcessorInfo.SupportedArchitectures'` |
| `MissingParameter` | A required parameter is absent (UNVERIFIED in the collected sources) | The message names the parameter |
| `DryRunOperation` | Not an error: `--dry-run` would have succeeded. Its opposite, `UnauthorizedOperation` on a dry run, means it would have failed | None needed |

## Reading SDK errors in TypeScript

The AWS SDK for JavaScript v3 throws an error whose `name` is the code. A retry loop might look like this:

```
catch (e) {
  if (e instanceof Error && e.name === "InvalidInstanceID.NotFound") { /* back off, retry */ }
}
```

The full code list is on the EC2 error-codes page. This catalogue covers the codes agents hit most.

Launches by Auto Scaling groups and Spot interruptions surface differently, as activity messages: `reference/ec2/auto-scaling-and-spot.md`.

## When none of these fits

Re-run the call with `--dry-run`, which checks permissions without launching. Decode any `Encoded authorization failure message` (`guides/iam/fix-access-denied.md`). Then search CloudTrail for the call's `errorCode` (`guides/cloudtrail/find-who-did-what.md`). Capacity errors change by AZ and instance type: try another subnet's AZ or a similar type before opening a case. Keep the request ID.


---
<!-- 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 -->
