aws-cloudformation / aws-cloudformation/cloudformation-coverage-roadmap
AWS::CE::AnomalyMonitor provider returns AlreadyExists/null for quota-exceeded errors (instead of ServiceLimitExceeded)
- 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
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