I was rolling out an AWS CDK application to production when my teammate ran cdk deploy and got an error about missing toolkit. We’d bootstrapped the account weeks ago, but apparently the bootstrap stack version was outdated. The deployment refused to proceed, and nothing worked until we re-bootstrapped. In this post, I’ll walk through exactly what causes this and how to fix it.
The Problem
CDK deployment fails with errors related to bootstrap or toolkit:
This stack uses assets, so the toolkit stack must be deployed to the environment
CDKToolkit stack version is outdated; did you update the CDK CLI?
Unable to assume role arn:aws:iam::123456789012:role/cdk-hnb659fds-cfn-exec-role
Common CDK bootstrap errors include:
| Error Type | Description |
|---|---|
| Missing toolkit stack | CDKToolkit CloudFormation stack doesn’t exist |
| Version mismatch | CDK CLI version is newer than bootstrap stack version |
| Permission denied | IAM role lacks permissions to create/update resources |
| Missing execution role | CDK assumes a role that doesn’t exist in target account |
| Cross-account bootstrap | Target account not bootstrapped with trust relationship to CI/CD account |
Why Does This Happen?
- CDK app never bootstrapped — The target account/region doesn’t have the
CDKToolkitCloudFormation stack. Bootstrap creates S3 bucket, ECR repository, IAM roles, and other infrastructure CDK needs. - CDK CLI version newer than bootstrap — You upgraded CDK CLI, but the bootstrap stack version is older. The older bootstrap lacks resources the new CDK needs.
- Insufficient IAM permissions — The role running
cdk deploydoesn’t have permissions to create CloudFormation stacks, S3 buckets, or IAM roles. - Cross-account deployment — Deploying from account A to account B requires account B to be bootstrapped with a trust relationship to account A.
- CDKToolkit stack manually deleted or modified — Someone deleted the bootstrap stack or removed critical resources (S3 bucket, execution role), breaking CDK deployments.
The Fix
Option 1: Bootstrap the Environment
If the environment was never bootstrapped, run bootstrap:
# Bootstrap default region of default AWS profile
cdk bootstrap
# Bootstrap specific account and region
cdk bootstrap aws://123456789012/us-east-1
# Bootstrap with custom parameters
cdk bootstrap \
--cloudformation-execution-policies arn:aws:iam::aws:policy/AdministratorAccess \
aws://123456789012/us-east-1
Option 2: Re-Bootstrap to Fix Version Mismatch
If CDK CLI version is newer than bootstrap stack, re-bootstrap:
# Check CDK CLI version
cdk --version
# Check bootstrap stack version
aws cloudformation describe-stacks \
--stack-name CDKToolkit \
--query "Stacks[0].Outputs[?OutputKey=='BootstrapVersion'].OutputValue" \
--output text
# Force re-bootstrap (overwrite existing stack)
cdk bootstrap --force aws://123456789012/us-east-1
Option 3: Bootstrap for Cross-Account Deployment
For deploying from account A to account B, bootstrap account B with trust to account A:
# In target account B, bootstrap with trust to source account A
# Replace 111111111111 with account A's ID
cdk bootstrap \
--trust 111111111111 \
aws://222222222222/us-east-1
# Or via AWS CLI for more control
aws cloudformation create-stack \
--stack-name CDKToolkit \
--template-url https://s3.amazonaws.com/aws-cdk/bootstrap/templates/bootstrap.json \
--parameters "ParameterKey=TrustedAccounts,ParameterValue=111111111111"
Option 4: Verify Bootstrap Stack Status
Check the bootstrap stack and its resources:
# Describe the CDKToolkit stack
aws cloudformation describe-stacks \
--stack-name CDKToolkit \
--query "Stacks[0].[StackStatus,StackStatusReason]"
# List CDKToolkit resources
aws cloudformation describe-stack-resources \
--stack-name CDKToolkit \
--query "StackResources[].{Type:ResourceType,LogicalId:LogicalResourceId,Status:ResourceStatus}"
# Check S3 bootstrap bucket exists
aws s3 ls | grep cdk
# Verify IAM execution role exists
aws iam get-role --role-name cdk-hnb659fds-cfn-exec-role
Option 5: Fix IAM Permissions for CDK
If IAM permissions are insufficient, add necessary policies to the user/role running cdk deploy:
# Check current user/role
aws sts get-caller-identity
# Create or update policy with CDK permissions
aws iam attach-user-policy \
--user-name my-user \
--policy-arn arn:aws:iam::aws:policy/AdministratorAccess
# Or for a more restricted policy, create a custom policy with CloudFormation + S3 + IAM rights
How to Run This
- Check if environment is bootstrapped:
aws cloudformation describe-stacks --stack-name CDKToolkit - If not bootstrapped:
cdk bootstrap aws://ACCOUNT_ID/REGION - If version mismatch:
cdk bootstrap --force aws://ACCOUNT_ID/REGION - For cross-account:
cdk bootstrap --trust SOURCE_ACCOUNT_ID aws://TARGET_ACCOUNT_ID/REGION - Verify bootstrap:
aws cloudformation describe-stacks --stack-name CDKToolkit --query "Stacks[0].StackStatus" - Deploy:
cdk deploy
Is This Safe?
Yes. Bootstrap is idempotent—running it multiple times is safe. Re-bootstrapping doesn’t delete or lose resources; it updates the CDKToolkit stack with any new resources the CDK version requires.
Key Takeaway
CDK deployment failures often stem from missing bootstrap, version mismatches, or insufficient permissions. Always bootstrap the target account before deploying, re-bootstrap when upgrading CDK CLI, and for cross-account deployments, bootstrap the target account with explicit trust to the source account.
Have questions or ran into a different CloudFormation issue? Connect with me on LinkedIn or X.