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

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 (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 (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:

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:

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:

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 and 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.

Have a question about this repo?

These articles cover the highlights, but your codebase questions are specific. Give your agent direct access to the source. Share this with your agent to get started:

Share the following with your agent to get started:
curl -s "https://instagit.com/install.md"

Works with
Claude Codex Cursor VS Code OpenClaw Any MCP Client

Maintain an open-source project? Get it listed too →