aws-cloudformation / aws-cloudformation/cloudformation-coverage-roadmap

AWS::CE::AnomalyMonitor provider returns AlreadyExists/null for quota-exceeded errors (instead of ServiceLimitExceeded)

Open
#2,515 0 comments 0 reactions 0 assignees View on GitHub
Dominant language
No language data
Stars
1.1k
Forks
62
PR merge metrics
No merged PRs in 30d

Description

## Summary

The `AWS::CE::AnomalyMonitor` CloudFormation resource provider mistranslates the AWS Cost Explorer service's `ValidationException("Limit exceeded on dimensional spend monitor creation")` (returned when you exceed the per-account quota of 1 DIMENSIONAL monitor per dimension) into the misleading CloudFormation event:

```
CREATE_FAILED AWS::CE::AnomalyMonitor
Resource handler returned message: "null"
(HandlerErrorCode: AlreadyExists)
```

This sends operators down a wrong-diagnosis path looking for a name collision when the actual cause is a service quota.

## Reproduction

In a single AWS account:

```yaml
Resources:
FirstMonitor:
Type: AWS::CE::AnomalyMonitor
Properties:
MonitorName: my-first-dim-service-monitor
MonitorType: DIMENSIONAL
MonitorDimension: SERVICE

SecondMonitor:
Type: AWS::CE::AnomalyMonitor
Properties:
MonitorName: my-second-dim-service-monitor
MonitorType: DIMENSIONAL
MonitorDimension: SERVICE
```

Deploy. The second monitor's create event fails with `HandlerErrorCode: AlreadyExists / message: null` even though no monitor with the name `my-second-dim-service-monitor` exists. Renaming the monitor does not help — the quota is per-dimension-per-account, not per-name.

## Evidence — actual AWS service error

CloudTrail (`EventName=CreateAnomalyMonitor`) shows the real underlying API response:

```json
{
"eventName": "CreateAnomalyMonitor",
"errorCode": "ValidationException",
"errorMessage": "Limit exceeded on dimensional spend monitor creation",
"requestParameters": {
"AnomalyMonitor": {
"MonitorName": "my-second-dim-service-monitor",
"MonitorType": "DIMENSIONAL",
"MonitorDimension": "SERVICE"
}
}
}
```

So AWS Cost Explorer correctly returns `ValidationException` with a precise `errorMessage`. The CFN provider drops the message (`null`) and labels the failure `AlreadyExists`.

## Why this is harmful (operator time cost)

A real-world report (anonymised): a 4-stack-attempt deploy + ~3 hours of triage on a stuck `UPDATE_FAILED` because `AlreadyExists` led the team to:
1. Sweep all regions for the supposedly-existing monitor — none found.
2. Hypothesise an AWS CE namespace tombstone after the previous create attempts.
3. Rename the monitor to dodge the tombstone, redeploy — same error.
4. Only then check CloudTrail and find the real `Limit exceeded` message.

A correct `HandlerErrorCode=ServiceLimitExceeded` + the original `errorMessage` would have cut this to 5 minutes.

## Expected behaviour

When the underlying service returns `ValidationException("Limit exceeded on …")`, the CFN provider should:
1. Use `HandlerErrorCode=ServiceLimitExceeded` (closer to the AWS standard for quota violations).
2. Pass the AWS service's `errorMessage` through to the CloudFormation event's message (or at minimum, never set `message=null`).

## Related provider scope

Likely the same mistranslation affects sibling resources whose CFN providers share the error-handling pattern:
- `AWS::CE::AnomalySubscription`
- `AWS::CE::CostCategory`

(Reporter did not reproduce these — flagging for the team to check.)

## Environment

- AWS Region: ap-northeast-1 (CE control plane runs out of us-east-1)
- CFN provider version: whatever was current on 2026-05-28 (the public version, no custom provider)

---

Filed by an operator who burned half a day on this; happy to share more CloudTrail samples privately if helpful.

Contributor guide

Open the contributing guide

Research direction

Start with the AWS::CE::AnomalyMonitor provider and reproduce the two-monitor CloudFormation example, then compare its failure event with the CloudTrail CreateAnomalyMonitor response. Done means quota ValidationException failures report ServiceLimitExceeded and preserve the service error message; check the related AnomalySubscription and CostCategory providers if they share the same handling.

Written by the indexing model from the issue text.

Assessment

Tech stack
aws
Domain
cloud
Issue type
Bug
Difficulty
4/5
Estimated time
3-5 days
Activity status
Quiet
Clarity
Mostly clear
Newbie friendliness
48/100

Get new issues in your inbox

A short digest of beginner-friendly GitHub issues.