Describe the bug
When destinationArn includes a prefix (e.g. arn:aws:s3:::my-bucket/guardduty), GuardDuty validates that the prefix exists as a folder — specifically, an S3 object with the key guardduty/. This validation is not documented as a hard requirement.
This silently breaks any Infrastructure-as-Code / CI-driven configuration flow (Terraform, CloudFormation custom resources, ad-hoc scripts) that re-asserts the publishing destination on every deploy against a bucket with lifecycle rules. The failure is invisible in day-to-day operations because findings keep flowing; it only surfaces on the next configuration change, often long after the underlying state was silently invalidated.
Regression Issue
Expected Behavior
- UpdatePublishingDestination with unchanged properties should succeed as a no-op. The destination is already in PUBLISHING state and continuously writing to the same destinationArn. Re-validating folder-marker existence adds no safety and breaks idempotent configuration flows (Terraform, CloudFormation custom resources, ad-hoc scripts).
- CreatePublishingDestination against a same-account bucket should not depend on a pre-existing folder marker. The documentation already commits to GuardDuty creating the "location" for same-account setups; that same auto-creation should tolerate — or restore — a marker that was subsequently deleted (e.g., by a bucket lifecycle rule) rather than failing the API call.
- If the folder-marker requirement is intentional and non-negotiable, then at minimum:
- The error message should identify what's actually being validated (e.g. "The S3 object '/' does not exist") rather than the ambiguous "resource folder does not exist," which sends operators down S3-permissions and bucket-existence rabbit holes.
- The requirement should be explicitly documented on the Exporting findings to S3 page, including its interaction with bucket lifecycle rules — since expiring lifecycle rules on log/audit buckets are common and this interaction is silent and non-obvious.
Current Behavior
The initial CreatePublishingDestination call succeeds and (per the docs) GuardDuty creates the folder marker automatically. However, if the destination bucket has any S3 lifecycle rule that expires objects (a very common configuration for log/audit buckets), the folder marker is deleted along with everything else. Findings continue to be published successfully — they're written as full-path objects under the prefix, independent of the marker — so the destination remains in PUBLISHING state indefinitely.
But any subsequent CreatePublishingDestination or UpdatePublishingDestination call — including a no-op update with unchanged properties — fails with:
BadRequestException: The request failed because the resource folder specified in the destinationArn parameter does not exist.
Type: InvalidInputException
Workaround: PutObject a zero-byte folder marker (aws s3api put-object --bucket <b> --key <prefix>/) immediately before every Create/Update call.
Reproduction Steps
- Create an S3 bucket with a lifecycle rule that expires objects (e.g. 30 days, no filter).
- Call
CreatePublishingDestination with a destinationArn that includes a prefix. Verify success and that GuardDuty is PUBLISHING.
- Wait for the lifecycle rule to expire the folder marker (
aws s3api head-object --key <prefix>/ returns 404).
- Call
CreatePublishingDestination or UpdatePublishingDestination again with any properties. Fails with the above error.
Possible Solution
Either:
- The API should not depend on the folder marker's continued existence (findings clearly don't), and the underlying validation should tolerate its absence and/or recreate it, or
- The error message should accurately describe what is being validated (e.g. "the S3 object
<prefix>/ was not found") so operators can diagnose it without inspecting internals.
Additional Information/Context
No response
CLI version used
2.35.15
Environment details (OS name and version, etc.)
Ubuntu 24.04.4 LTS (Github Runner)
Describe the bug
When
destinationArnincludes a prefix (e.g.arn:aws:s3:::my-bucket/guardduty), GuardDuty validates that the prefix exists as a folder — specifically, an S3 object with the keyguardduty/. This validation is not documented as a hard requirement.This silently breaks any Infrastructure-as-Code / CI-driven configuration flow (Terraform, CloudFormation custom resources, ad-hoc scripts) that re-asserts the publishing destination on every deploy against a bucket with lifecycle rules. The failure is invisible in day-to-day operations because findings keep flowing; it only surfaces on the next configuration change, often long after the underlying state was silently invalidated.
Regression Issue
Expected Behavior
Current Behavior
The initial
CreatePublishingDestinationcall succeeds and (per the docs) GuardDuty creates the folder marker automatically. However, if the destination bucket has any S3 lifecycle rule that expires objects (a very common configuration for log/audit buckets), the folder marker is deleted along with everything else. Findings continue to be published successfully — they're written as full-path objects under the prefix, independent of the marker — so the destination remains inPUBLISHINGstate indefinitely.But any subsequent
CreatePublishingDestinationorUpdatePublishingDestinationcall — including a no-op update with unchanged properties — fails with:Workaround:
PutObjecta zero-byte folder marker (aws s3api put-object --bucket <b> --key <prefix>/) immediately before everyCreate/Updatecall.Reproduction Steps
CreatePublishingDestinationwith adestinationArnthat includes a prefix. Verify success and that GuardDuty isPUBLISHING.aws s3api head-object --key <prefix>/returns 404).CreatePublishingDestinationorUpdatePublishingDestinationagain with any properties. Fails with the above error.Possible Solution
Either:
<prefix>/was not found") so operators can diagnose it without inspecting internals.Additional Information/Context
No response
CLI version used
2.35.15
Environment details (OS name and version, etc.)
Ubuntu 24.04.4 LTS (Github Runner)