ERROR REFERENCE
S3 error: Access Denied (deployment bucket)
sam deploy failed talking to its artifact bucket: either
the upload was rejected, or CloudFormation could not read the
uploaded template and zip back out of S3. The two directions fail for
different identities, and the fix depends on which one you have.
WHAT IT MEANS
What this error means
An error occurred (ValidationError) when calling the CreateChangeSet operation: S3 error: Access Denied— the readback direction: CloudFormation, not your CLI, could not fetch the artifacts.An error occurred (AccessDenied) when calling the PutObject operationwhile uploading — the upload direction: your deploy credentials cannot write to the bucket.
Common causes, roughly in order of frequency:
- a
samconfig.tomls3_bucketpointing at a bucket in the wrong Region; - a bucket owned by another account (shared or copied config);
- SSE-KMS on the bucket without matching key permissions for the deploy identity;
- a bucket policy or Block Public Access change that tightened access after the bucket was configured.
FIX
How to fix it
-
Separate the directions (read-only):
If your credentials can read the object, the upload worked and the failure is CloudFormation's readback — look at bucket policy and KMS. If head-object is denied too, the problem is your deploy identity's access.aws s3api head-object --bucket my-deploy-bucket --key path/from/the/error -
Catch the wrong-Region bucket:
The bucket's Region must match the Region you deploy to; SAM's managed bucket (aws s3api get-bucket-location --bucket my-deploy-bucket--resolve-s3) avoids this class entirely. -
Check encryption:
SSE-KMS buckets need the deploy identity to hold key permissions alongside the S3 permissions.aws s3api get-bucket-encryption --bucket my-deploy-bucket - Confirm ownership before touching policy. If the bucket belongs to another account, coordinate rather than widening a policy you do not own.
AUTOMATE THE TRIAGE
Diagnose this automatically
SAM Doctor recognizes both directions (high confidence) and keeps IAM-worded denials with the IAM rules, which name the policy layer instead. Runs locally; no AWS access, no log upload.
python -m pip install sam-doctor
sam-doctor diagnose deployment.log --format markdown
RELATED
Related errors
- Access denied with an explicit deny — when the denial names a policy layer instead of S3.
- BucketAlreadyExists — the other way an S3 bucket stops a deploy cold.