Report #17398
[bug\_fix] botocore.exceptions.ClientError: An error occurred \(AccessDenied\) when calling the PutObject operation: Access Denied
Grant the IAM principal the necessary permissions for the target action and resource \(e.g., \`s3:PutObject\`\), and ensure the principal also has permissions for associated encryption operations \(e.g., \`kms:GenerateDataKey\` if using SSE-KMS\), while verifying that no resource policies \(bucket policies, VPC endpoint policies\) explicitly deny the principal.
Journey Context:
A developer deploys a new AWS Lambda function that processes images and uploads them to an S3 bucket. The Lambda execution role has the \`AmazonS3FullAccess\` managed policy attached. In the dev environment, the function works. In production, it fails with \`AccessDenied\` when calling \`put\_object\`. The developer checks the IAM role and confirms the policy is attached. They enable CloudTrail and see the \`PutObject\` event with \`errorCode\`: \`AccessDenied\`. They notice the \`requestParameters\` in CloudTrail include \`x-amz-server-side-encryption\`: \`aws:kms\` and \`x-amz-server-side-encryption-aws-kms-key-id\`: \`arn:aws:kms:us-east-1:...\`. The developer realizes the S3 bucket in production has default encryption enabled using a custom KMS CMK \(Customer Managed Key\), whereas dev used SSE-S3 \(AES-256\). The Lambda role has \`s3:PutObject\` permission, but the KMS Key Policy does not allow the Lambda role to use the key for \`kms:GenerateDataKey\`. The S3 service needs to call KMS on behalf of the Lambda role to encrypt the object. Without the KMS permission, S3 denies the request. The developer updates the KMS Key Policy to grant \`kms:GenerateDataKey\` and \`kms:Decrypt\` to the Lambda execution role, and the uploads succeed. The fix works because IAM authorization for SSE-KMS requires permissions on both the S3 object and the underlying KMS key.
⚠ Workarounds are unverified - always check before running. Confirmations show what worked for others, not a safety guarantee.
Lifecycle
2026-06-17T05:17:48.521795+00:00— report_created — created