A security engineer is troubleshooting an issue where CloudTrail logs are not being delivered to the specified S3 bucket. The bucket policy allows CloudTrail to write objects. What is the MOST likely cause?
Trap 1: The S3 bucket uses server-side encryption with customer-provided…
SSE-C is a per-object encryption mode, not a bucket-level default, and it is not supported by CloudTrail for log delivery. CloudTrail automatically uses SSE-S3 for new buckets and can optionally use SSE-KMS, but it cannot supply the customer-provided key headers required for SSE-C. Even if an encryption mismatch occurred, it would surface as an S3 encryption error rather than an Access Denied caused by a bucket policy deny.
Trap 2: The S3 bucket does not have versioning enabled.
Versioning is an optional bucket property for CloudTrail log storage, not a prerequisite for writing new objects. When versioning is disabled, CloudTrail still successfully delivers log files; the only impact is that overwritten or deleted versions are not retained. Since a delivery failure would appear as an authorization or access error rather than a versioning-related error, the absence of versioning cannot explain the issue.
Trap 3: The S3 bucket is in a different AWS account.
CloudTrail explicitly supports delivering logs to an S3 bucket in a different AWS account, provided the bucket policy includes the appropriate cross-account Allow statements for the CloudTrail service principal and the expected AWSLogs prefix. A remote bucket alone does not prevent delivery; only a missing or misconfigured resource policy would. Therefore, the bucket's account location is not inherently the cause, and the contents of the bucket policy are what should be examined.
- A
The S3 bucket uses server-side encryption with customer-provided keys (SSE-C).
Why it fails: SSE-C is a per-object encryption mode, not a bucket-level default, and it is not supported by CloudTrail for log delivery. CloudTrail automatically uses SSE-S3 for new buckets and can optionally use SSE-KMS, but it cannot supply the customer-provided key headers required for SSE-C. Even if an encryption mismatch occurred, it would surface as an S3 encryption error rather than an Access Denied caused by a bucket policy deny.
- B
The S3 bucket has a bucket policy that denies access to the CloudTrail service principal.
An explicit Deny statement in the destination bucket policy that references the CloudTrail service principal (cloudtrail.amazonaws.com) will override any Allow that CloudTrail receives through its service role or resource-based policies. In AWS IAM policy evaluation, an explicit deny acts as an absolute veto, so CloudTrail's attempts to perform s3:PutObject and s3:GetBucketAcl fail with Access Denied. Because this would block delivery regardless of encryption, versioning, or account location, it is the likely root cause.
- C
The S3 bucket does not have versioning enabled.
Why it fails: Versioning is an optional bucket property for CloudTrail log storage, not a prerequisite for writing new objects. When versioning is disabled, CloudTrail still successfully delivers log files; the only impact is that overwritten or deleted versions are not retained. Since a delivery failure would appear as an authorization or access error rather than a versioning-related error, the absence of versioning cannot explain the issue.
- D
The S3 bucket is in a different AWS account.
Why it fails: CloudTrail explicitly supports delivering logs to an S3 bucket in a different AWS account, provided the bucket policy includes the appropriate cross-account Allow statements for the CloudTrail service principal and the expected AWSLogs prefix. A remote bucket alone does not prevent delivery; only a missing or misconfigured resource policy would. Therefore, the bucket's account location is not inherently the cause, and the contents of the bucket policy are what should be examined.