aws / aws/aws-cdk

(aws_certificate_manager): ACM Certificate deletion fails with "ResourceInUseException" when used by API Gateway Custom Domain

Open
#36,265 17 comments 11 reactions 0 assignees View on GitHub
@aws-cdk/aws-certificatemanager bug p2 potential-regression
Dominant language
TypeScript
Stars
12.9k
Forks
4.6k
Avg merge
2d 3h
Merged PRs (30d)
83

Description

### Describe the bug

When destroying a CDK stack that contains an ACM Certificate used by an API Gateway Custom Domain, the deletion fails with `ResourceInUseException:
Certificate is in use` even though the Custom Domain should be deleted first.

This occurs because AWS doesn't immediately release the certificate association after the Custom Domain is deleted - there's an eventual consistency delay. CloudFormation then attempts to delete the certificate and fails.

### What We Tried

- Adding explicit dependency: customDomain.node.addDependency(certificate) - Does not work
- The dependency ensures CloudFormation deletes the Custom Domain first, but AWS doesn't immediately release the certificate association

### Regression Issue

- [x] Select this option if this issue appears to be a regression.

### Last Known Working CDK Library Version

_No response_

### Expected Behavior

Stack should destroy successfully, with the Custom Domain deleted before the Certificate.

### Current Behavior

Stack enters DELETE_FAILED state because the certificate is still reported as "in use" by AWS even after the Custom Domain resource has been deleted.

### Reproduction Steps

1. Deploy the minimal reproduction stack below
2. Run `cdk destroy --force`
3. Observe the deletion failure

```typescript
import * as cdk from 'aws-cdk-lib';
import { aws_certificatemanager, aws_route53, Stack, StackProps } from 'aws-cdk-lib';
import * as apigateway from 'aws-cdk-lib/aws-apigateway';
import { Construct } from 'constructs';

export class CertDeletionTestStack extends Stack {
constructor(scope: Construct, id: string, props?: StackProps) {
super(scope, id, props);

const domain = 'example.com'; // Replace with your domain

const hostedZone = aws_route53.HostedZone.fromLookup(this, 'HostedZone', {
domainName: domain,
});

const domainName = `cert-test.${domain}`;

const certificate = new aws_certificatemanager.Certificate(this, 'Certificate', {
domainName,
validation: aws_certificatemanager.CertificateValidation.fromDns(hostedZone),
});

const api = new apigateway.RestApi(this, 'TestApi', {
restApiName: 'cert-deletion-test-api',
});

api.root.addMethod('GET', new apigateway.MockIntegration({}));

const customDomain = new apigateway.DomainName(this, 'CustomDomain', {
domainName,
certificate,
});

// This does NOT fix the issue - the problem is AWS-level eventual consistency
customDomain.node.addDependency(certificate);

customDomain.addApiMapping(api.deploymentStage);
}
}

const app = new cdk.App();
new CertDeletionTestStack(app, 'cert-deletion-test', {
env: {
account: process.env.CDK_DEFAULT_ACCOUNT,
region: 'eu-west-1',
},
});
```

```
Error Message

cert-deletion-test: destroy failed ToolkitError: The stack named cert-deletion-test is in a failed state. You may need to delete it from the AWS
console : DELETE_FAILED (The following resource(s) failed to delete: [CertificateXXXXXXXX]. ): Certificate
arn:aws:acm:eu-west-1:XXXXXXXXXXXX:certificate/XXXXXXXX-XXXX-XXXX-XXXX-XXXXXXXXXXXX in account XXXXXXXXXXXX is in use. (Service:
AWSCertificateManager; Status Code: 400; Error Code: ResourceInUseException; Request ID: XXXXXXXX-XXXX-XXXX-XXXX-XXXXXXXXXXXX; Proxy: null)
```

### Possible Solution

_No response_

### Additional Information/Context

This didn't use to be an issue, something changed around ~Oct 30th with CDK or AWS and we started to see this

### AWS CDK Library version (aws-cdk-lib)

2.231.0

### AWS CDK CLI version

2.1027.0 (build 5fc1b13)

### Node.js Version

22

### OS

macOS 26.1

### Language

TypeScript

### Language Version

_No response_

### Other information

_No response_

Contributor guide

Open the contributing guide

Research direction

Start by reproducing the failure with the provided TypeScript stack, then inspect the aws_certificatemanager.Certificate and apigateway.DomainName entry points involved in deletion ordering. A complete fix should allow cdk destroy to delete the custom domain and subsequently remove the certificate without ResourceInUseException.

Written by the indexing model from the issue text.

Assessment

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

Get new issues in your inbox

A short digest of beginner-friendly GitHub issues.