# How to Fix AWS CDK Non-Empty S3 Bucket Deletion Issues with autoDeleteObjects

> Troubleshoot AWS CDK non-empty S3 bucket deletion issues. Learn how to use autoDeleteObjects and DESTROY removal policy to ensure successful bucket removal and object deletion.

- Repository: [Amazon Web Services/agent-toolkit-for-aws](https://github.com/aws/agent-toolkit-for-aws)
- Tags: how-to-guide
- Published: 2026-07-01

---

**To successfully delete an AWS CDK S3 bucket that contains objects or versioned data, you must set both `removalPolicy: cdk.RemovalPolicy.DESTROY` and `autoDeleteObjects: true` in your bucket construct.**

The `aws/agent-toolkit-for-aws` repository provides authoritative guidance on handling S3 bucket lifecycle management in CDK applications. When destroying CloudFormation stacks containing S3 buckets, developers frequently encounter "bucket is not empty" errors because CloudFormation cannot delete buckets containing objects, delete markers, or non-current versions. The CDK's `autoDeleteObjects` flag solves this by automatically provisioning a custom-resource Lambda function that empties the bucket before CloudFormation attempts deletion.

## Why removalPolicy.DESTROY Alone Cannot Delete Non-Empty Buckets

Setting `removalPolicy: cdk.RemovalPolicy.DESTROY` on an S3 bucket instructs CloudFormation to remove the bucket resource when the stack is destroyed. However, CloudFormation's native behavior prevents the deletion of any bucket that still contains data.

According to the source code in [`skills/core-skills/aws-cdk/SKILL.md`](https://github.com/aws/agent-toolkit-for-aws/blob/main/skills/core-skills/aws-cdk/SKILL.md) (line 23), this limitation affects both standard buckets containing objects and versioned buckets with delete markers or non-current versions. When CloudFormation attempts to delete a non-empty bucket, the operation fails and rolls back, leaving the bucket intact while potentially creating the impression that the stack was removed successfully.

The issue becomes particularly problematic with **versioned buckets**, where standard object deletion APIs remove only the latest version, leaving historical data and delete markers that still block bucket deletion.

## How autoDeleteObjects Solves the Deletion Problem

The `autoDeleteObjects` property triggers CDK to create a custom-resource Lambda function that executes before CloudFormation attempts to delete the bucket. This Lambda iterates through every object, version, and delete marker in the bucket, removing them completely to ensure the bucket is truly empty when CloudFormation performs the final deletion.

As documented in [`skills/core-skills/aws-cdk/references/troubleshooting-deployment.md`](https://github.com/aws/agent-toolkit-for-aws/blob/main/skills/core-skills/aws-cdk/references/troubleshooting-deployment.md) (lines 23-31), this automated cleanup runs during the stack destruction phase and requires no additional code in your stack definition beyond setting the boolean flag to `true`.

## Implementation Examples for Different Scenarios

### Basic Bucket Configuration

For a simple development bucket that should be completely removed when the stack is destroyed:

```typescript
import * as cdk from 'aws-cdk-lib';
import * as s3 from 'aws-cdk-lib/aws-s3';

export class DemoStack extends cdk.Stack {
  constructor(scope: cdk.App, id: string, props?: cdk.StackProps) {
    super(scope, id, props);

    new s3.Bucket(this, 'DemoBucket', {
      // Delete the bucket when the stack is destroyed
      removalPolicy: cdk.RemovalPolicy.DESTROY,
      // Also delete **all** objects automatically
      autoDeleteObjects: true,
    });
  }
}

```

### Versioned Buckets

Versioned buckets require the same flags, as the cleanup process must handle all object versions and delete markers:

```typescript
new s3.Bucket(this, 'VersionedBucket', {
  versioned: true,
  removalPolicy: cdk.RemovalPolicy.DESTROY,
  autoDeleteObjects: true,   // crucial for removing all versions
});

```

### Environment-Specific Policies

For stacks deployed across multiple environments, conditionally apply destruction policies to prevent accidental production data loss:

```typescript
const isProd = this.node.tryGetContext('environment') === 'prod';

new s3.Bucket(this, 'ProdBucket', {
  removalPolicy: isProd ? cdk.RemovalPolicy.RETAIN : cdk.RemovalPolicy.DESTROY,
  // Only enable auto-delete for non-production environments
  autoDeleteObjects: !isProd,
});

```

## Production Safety Considerations

The `autoDeleteObjects` functionality is designed for **development and test environments** where temporary infrastructure is frequently created and destroyed. Production buckets should retain the default `RETAIN` removal policy to prevent accidental data loss during stack updates or deletions.

The custom-resource Lambda created by CDK is fully managed and automatically removed along with the stack, requiring no manual cleanup or additional IAM configuration beyond what CDK provisions.

## Summary

- **Both flags are required**: Setting only `removalPolicy: cdk.RemovalPolicy.DESTROY` without `autoDeleteObjects: true` results in deployment failures for non-empty buckets.
- **Handles versioning**: The `autoDeleteObjects` Lambda removes all object versions and delete markers, not just current objects.
- **Development-focused**: Reserve this configuration for development and testing environments; use `RETAIN` for production data.
- **Automatic cleanup**: CDK manages the custom-resource Lambda lifecycle; no additional code is required beyond setting the boolean flag.
- **Source locations**: Detailed guidance exists in [`skills/core-skills/aws-cdk/SKILL.md`](https://github.com/aws/agent-toolkit-for-aws/blob/main/skills/core-skills/aws-cdk/SKILL.md) and [`skills/core-skills/aws-cdk/references/troubleshooting-deployment.md`](https://github.com/aws/agent-toolkit-for-aws/blob/main/skills/core-skills/aws-cdk/references/troubleshooting-deployment.md) within the `aws/agent-toolkit-for-aws` repository.

## Frequently Asked Questions

### What happens if I only set removalPolicy to DESTROY without autoDeleteObjects?

CloudFormation will attempt to delete the bucket but fail with a "bucket is not empty" error, causing the stack destruction to roll back. The bucket will remain intact with all its data, potentially leaving the stack in an inconsistent state where resources appear removed but the bucket persists.

### Does autoDeleteObjects work with versioned S3 buckets?

Yes, the custom-resource Lambda function invoked by `autoDeleteObjects` specifically handles versioned buckets by iterating through and deleting all object versions and delete markers. This is essential because versioned buckets cannot be deleted even if the "current" objects are removed, as non-current versions remain in storage.

### Is the autoDeleteObjects Lambda function visible in my CDK code?

No, the Lambda function is created automatically by the CDK framework as a custom resource when you set `autoDeleteObjects: true`. It does not appear in your stack code, but you will see it in the synthesized CloudFormation template and AWS console as part of the stack's resources. CDK manages the function's IAM permissions and lifecycle automatically.

### Can I use autoDeleteObjects in production environments?

While technically possible, it is strongly discouraged according to the `aws/agent-toolkit-for-aws` guidance. Production buckets should use `cdk.RemovalPolicy.RETAIN` (the default) to prevent accidental data loss during stack updates or deletions. The `autoDeleteObjects` feature is intended for ephemeral development and testing infrastructure where complete resource cleanup is desired.