Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Conflicting S3 Lifecycle Rule Filter #367

Closed
AaronStarr-pga opened this issue Dec 4, 2024 · 5 comments
Closed

Conflicting S3 Lifecycle Rule Filter #367

AaronStarr-pga opened this issue Dec 4, 2024 · 5 comments
Assignees
Labels
bug This issue is a bug. module/powershell-cmdlets p2 This is a standard priority issue response-requested Waiting on additional info and feedback. Will move to "closing-soon" in 7 days.

Comments

@AaronStarr-pga
Copy link

AaronStarr-pga commented Dec 4, 2024

Describe the bug

When calling Get-S3LifecycleConfiguration on a bucket that has a lifecycle policy + rule on it, where the rule scope is applied to all items in the bucket (So no Filter), you will receive a LifecycleRule as expected, however, the Filter field in the rule will be empty.

If you were to take that rule and then run Write-S3LifecycleConfiguration with it, you'd receive and XML format error. This is because the Filter is missing. To update a policy, you need to pull down the rules and fill in all the empty Filter fields with new Amazon.S3.Model.LifecycleFilter objects.

Expected Behavior

Either the Get-S3LifecycleConfiguration should provide rules with the empty filter object or the Write-S3LifecycleConfiguration should not require a Filter object to have correct XML format

Current Behavior

AbortIncompleteMultipartUpload : Amazon.S3.Model.LifecycleRuleAbortIncompleteMultipartUpload
Expiration :
Id : DeleteIncompleteMultipart
NoncurrentVersionExpiration :
Filter :
Status : Enabled
NoncurrentVersionTransitions : {}
Transitions : {}

Write-S3LifecycleConfiguration : The XML you provided was not well-formed or did not validate against our published schema

Reproduction Steps

Create a bucket in S3, add a Policy/rule to it so the rule's scope is the entire bucket.
Use AWS.Tools.S3.Get-S3LifecycleConfiguration to pull it down and isolate the Amazon.S3.Model.LifecycleRule inside.
Take this rule and use it to run Write-S3LifecycleConfiguration.
XML format error

Possible Solution

As stated above, either have the filter get correctly pulled down as an empty Amazon.S3.Model.LifecycleFilter object ([Amazon.S3.Model.LifecycleFilter]::new()) or don't require Write-S3LifecycleConfiguration's parameter Configuration_Rule to need an empty filter to determine it has a scope that includes the whole bucket.

Additional Information/Context

No response

AWS Tools for PowerShell version used

AWS.Tools.S3 | 4.1.705
AWS.Tools.Common | 4.1.705

PowerShell version used

Major Minor Build Revision
5 1 22621 4391

Operating System and version

Windows 11 Enterprise, 23H2

@AaronStarr-pga AaronStarr-pga added bug This issue is a bug. needs-triage This issue or PR still needs to be triaged. labels Dec 4, 2024
@ashishdhingra ashishdhingra added module/powershell-cmdlets p2 This is a standard priority issue needs-reproduction This issue needs reproduction. and removed needs-triage This issue or PR still needs to be triaged. labels Dec 4, 2024
@ashishdhingra
Copy link
Contributor

ashishdhingra commented Dec 4, 2024

Analysis
Issue is reproducible. Below are the findings:


Looks like in customer's use case, Lifecycle rule configuration the rule scope is set as Apply to all objects in the bucket (this changes rule scope to Entire bucket). Enabled verbose response logging for AWS Tools for PowerShell (refer Response Logging in AWS Tools for Windows PowerShell for details) and executed $getlifecycleconfigurationresponse = Get-S3LifecycleConfiguration -BucketName testbucket-issue367 PowerShell CmdLet. Below is the response in verbose logging:

...
Amazon Information: 5 : Request metrics: AsyncCall = True; CanonicalRequest = GET\n/\nlifecycle=\nhost:testbucket-issue367.s3.us-east-2.amazonaws.com\nuser-agent:AWSPowerShell.Common/4.1.711.0 ua/2.0 os/windows#10.0.19045.0 md/ARCH#X64 lang/.NET_Core#8.0.8 md/aws-sdk-dotnet-core#3.7.400.59 api/S3#3.7.410.1 md/PowerShellCore/7.-1 cfg/retry-mode#legacy md/ClientAsync cfg/init-coll#1\nx-amz-content-sha256:e3b0c44298fc1c149afbf4c8996fb92427ae41e4649b934ca495991b7852b855\nx-amz-date:20241204T210217Z\nx-amz-security-token:<<TOKEN-REDACTED>>\n\nhost;user-agent;x-amz-content-sha256;x-amz-date;x-amz-security-token\ne3b0c44298fc1c149afbf4c8996fb92427ae41e4649b934ca495991b7852b855; StringToSign = AWS4-HMAC-SHA256\n20241204T210217Z\n20241204/us-east-2/s3/aws4_request\n49be41a57d6041713c2e188ad199eeed4daa7c44a7e785a1a50ebf0be03a711a; ServiceName = AmazonS3; ServiceEndpoint = https://testbucket-issue367.s3.us-east-2.amazonaws.com/; MethodName = GetLifecycleConfigurationRequest; AmzId2 = DmWjzQT8WlzmNqDT0ZydJmxhs/GH8Em/uLeJeRj5r9xesf6C3uJEzhEWvPAkM8NKYiIe+RU83hmu8eFzkn8C2S6v5sVp1aG9O+CJ3fHXAEY=; StatusCode = OK; BytesProcessed = 338; AWSRequestID = S0G0WWK71YYY92BM; CredentialsRequestTime = 00:00:01.9339616; RequestSigningTime = 00:00:00.0004549; HttpRequestTime = 00:00:00.2713438; ResponseUnmarshallTime = 00:00:00.0001935; ResponseProcessingTime = 00:00:00.0005850; ClientExecuteTime = 00:00:02.2071163; 
Amazon Information: 3 : Resolved DefaultConfigurationMode for RegionEndpoint [us-east-2] to [Legacy].
Amazon Information: 6 : Starting a process with the following ProcessInfo: UseShellExecute - False RedirectStandardError - True, RedirectStandardOutput - True, CreateNoWindow - True
Amazon Information: 7 : Process started
Amazon Information: 3 : Process ends with exitcode - 0
Amazon Verbose: 6 : Received response (truncated to 1024 bytes): [<?xml version="1.0" encoding="UTF-8"?>
<LifecycleConfiguration xmlns="http://s3.amazonaws.com/doc/2006-03-01/"><Rule><ID>testglacierrule</ID><Filter/><Status>Enabled</Status><Transition><Days>0</Days><StorageClass>GLACIER_IR</StorageClass></Transition></Rule></LifecycleConfiguration>]
...

As noted, it returns empty <Filter/> element since the scope is set to entire bucket.

Using the similar AWS CLI command aws s3api get-bucket-lifecycle-configuration --bucket testbucket-issue367 --debug returns the below output:

2024-12-04 13:10:40,690 - MainThread - botocore.httpsession - DEBUG - Certificate path: C:\Program Files\Amazon\AWSCLIV2\awscli\botocore\cacert.pem
2024-12-04 13:10:40,690 - MainThread - urllib3.connectionpool - DEBUG - Starting new HTTPS connection (1): testbucket-issue367.s3.us-east-2.amazonaws.com:443
2024-12-04 13:10:41,344 - MainThread - urllib3.connectionpool - DEBUG - https://testbucket-issue367.s3.us-east-2.amazonaws.com:443 "GET /?lifecycle HTTP/1.1" 200 284
2024-12-04 13:10:41,344 - MainThread - botocore.parsers - DEBUG - Response headers: {'x-amz-id-2': 'N3EDDwsUD4iMCgrHXw8zM61Pyzznt7sv85JC7w/mkiWkmQj3HbW61KL/HuJpovNkzyLjmWybz7Xugyv4UTgMDw==', 'x-amz-request-id': 'GKY5MSKC823FNPMS', 'Date': 'Wed, 04 Dec 2024 21:10:42 GMT', 'x-amz-transition-default-minimum-object-size': 'all_storage_classes_128K', 'Content-Length': '284', 'Server': 'AmazonS3'}
2024-12-04 13:10:41,344 - MainThread - botocore.parsers - DEBUG - Response body:
b'<?xml version="1.0" encoding="UTF-8"?>\n<LifecycleConfiguration xmlns="http://s3.amazonaws.com/doc/2006-03-01/"><Rule><ID>testglacierrule</ID><Filter/><Status>Enabled</Status><Transition><Days>0</Days><StorageClass>GLACIER_IR</StorageClass></Transition></Rule></LifecycleConfiguration>'
2024-12-04 13:10:41,344 - MainThread - botocore.hooks - DEBUG - Event needs-retry.s3.GetBucketLifecycleConfiguration: calling handler <bound method RetryHandler.needs_retry of <botocore.retries.standard.RetryHandler object at 0x00000246AA3A9990>>
2024-12-04 13:10:41,344 - MainThread - botocore.retries.standard - DEBUG - Not retrying request.
2024-12-04 13:10:41,344 - MainThread - botocore.hooks - DEBUG - Event needs-retry.s3.GetBucketLifecycleConfiguration: calling handler <bound method S3RegionRedirectorv2.redirect_from_error of <botocore.utils.S3RegionRedirectorv2 object at 0x00000246AA332990>>
2024-12-04 13:10:41,344 - MainThread - botocore.hooks - DEBUG - Event after-call.s3.GetBucketLifecycleConfiguration: calling handler <function enhance_error_msg at 0x00000246A8AA36A0>
2024-12-04 13:10:41,344 - MainThread - botocore.hooks - DEBUG - Event after-call.s3.GetBucketLifecycleConfiguration: calling handler <bound method RetryQuotaChecker.release_retry_quota of <botocore.retries.standard.RetryQuotaChecker object at 0x00000246A9F03310>>
2024-12-04 13:10:41,344 - MainThread - awscli.formatter - DEBUG - RequestId: GKY5MSKC823FNPMS
{
    "Rules": [
        {
            "ID": "testglacierrule",
            "Filter": {},
            "Status": "Enabled",
            "Transitions": [
                {
                    "Days": 0,
                    "StorageClass": "GLACIER_IR"
                }
            ]
        }
    ]
}

Clearly the S3 GetBucketLifecycleConfiguration service API operation is returning empty filter element, which is processed properly properly by AWS Tools for PowerShell (and AWS CLI).

While executing Write-S3LifecycleConfiguration -BucketName testbucket-issue1880 -Configuration_Rule $getlifecycleconfigurationresponse.Rules, it indeed gives error Write-S3LifecycleConfiguration: The XML you provided was not well-formed or did not validate against our published schema.

Capturing network traffic shows the below request body being sent:

<LifecycleConfiguration xmlns="http://s3.amazonaws.com/doc/2006-03-01/">
    <Rule>
        <Transition>
            <Days>0</Days>
            <StorageClass>GLACIER_IR</StorageClass>
        </Transition>
        <ID>testglacierrule</ID>
        <Status>Enabled</Status>
    </Rule>
</LifecycleConfiguration>

Changing the ID in PowerShell object still gives the same error. The error is returned by the AWS S3 API. The above XML conforms to request body schema at PutBucketLifecycleConfiguration.

Need to do more analysis, like comparing with Java SDK and/or AWS CLI. Most likely we need to open issue with S3 service team.

@ashishdhingra ashishdhingra added investigating This issue is being investigated and/or work is in progress to resolve the issue. and removed needs-reproduction This issue needs reproduction. labels Dec 4, 2024
@ashishdhingra ashishdhingra self-assigned this Dec 4, 2024
@ashishdhingra
Copy link
Contributor

ashishdhingra commented Dec 5, 2024

Running below Java SDK code:

package org.example;

import software.amazon.awssdk.core.ResponseBytes;
import software.amazon.awssdk.core.sync.RequestBody;
import software.amazon.awssdk.http.apache.ApacheHttpClient;
import software.amazon.awssdk.services.s3.S3Client;
import software.amazon.awssdk.services.s3.model.*;
import software.amazon.encryption.s3.S3EncryptionClient;

public class Handler {
    public void sendRequest() {
        String bucketName = "testbucket-issue1880";

        S3Client s3Client = S3Client.builder().httpClientBuilder(
                ApacheHttpClient.builder().maxConnections(100)
        ).build();
        GetBucketLifecycleConfigurationResponse getBucketLifecycleConfigurationResponse =
                s3Client.getBucketLifecycleConfiguration(
                        GetBucketLifecycleConfigurationRequest.builder().bucket(
                                bucketName
                        ).build()
                );
        PutBucketLifecycleConfigurationResponse putBucketLifecycleConfigurationResponse =
                s3Client.putBucketLifecycleConfiguration(
                        PutBucketLifecycleConfigurationRequest.builder()
                                .bucket(bucketName)
                                .lifecycleConfiguration(
                                        BucketLifecycleConfiguration.builder()
                                                .rules(getBucketLifecycleConfigurationResponse.rules()
                                                ).build()
                                ).build());
    }
}

logs below in verbose logs:

2024-12-05 14:41:53 [main] DEBUG software.amazon.awssdk.http.apache.internal.conn.SdkTlsSocketFactory:484 -  peer alternative names: [*.s3.us-east-2.amazonaws.com, s3.us-east-2.amazonaws.com, *.s3-us-east-2.amazonaws.com, s3-us-east-2.amazonaws.com, *.s3.dualstack.us-east-2.amazonaws.com, s3.dualstack.us-east-2.amazonaws.com, *.s3.amazonaws.com, *.s3-control.us-east-2.amazonaws.com, s3-control.us-east-2.amazonaws.com, *.s3-control.dualstack.us-east-2.amazonaws.com, s3-control.dualstack.us-east-2.amazonaws.com, *.s3-accesspoint.us-east-2.amazonaws.com, *.s3-accesspoint.dualstack.us-east-2.amazonaws.com, *.s3-deprecated.us-east-2.amazonaws.com, s3-deprecated.us-east-2.amazonaws.com]
2024-12-05 14:41:53 [main] DEBUG software.amazon.awssdk.http.apache.internal.conn.SdkTlsSocketFactory:488 -  issuer principal: CN=Amazon RSA 2048 M01, O=Amazon, C=US
2024-12-05 14:41:53 [main] DEBUG org.apache.http.wire:73 - http-outgoing-0 >> "GET /?lifecycle HTTP/1.1[\r][\n]"
...
...
2024-12-05 14:41:53 [main] DEBUG org.apache.http.wire:73 - http-outgoing-0 >> "Connection: Keep-Alive[\r][\n]"
2024-12-05 14:41:53 [main] DEBUG org.apache.http.wire:73 - http-outgoing-0 >> "[\r][\n]"
2024-12-05 14:41:53 [main] DEBUG org.apache.http.wire:73 - http-outgoing-0 << "HTTP/1.1 200 OK[\r][\n]"
2024-12-05 14:41:53 [main] DEBUG org.apache.http.wire:73 - http-outgoing-0 << "x-amz-id-2: OutiawFhABSRYd4bvByXvJsPSgBah9llKmiukhRgBIO2KtsXJZcmO/nEEv7cbhU1LVI5z+Zf2Jg=[\r][\n]"
2024-12-05 14:41:53 [main] DEBUG org.apache.http.wire:73 - http-outgoing-0 << "x-amz-request-id: BP29JKDRGSNK6B6K[\r][\n]"
2024-12-05 14:41:53 [main] DEBUG org.apache.http.wire:73 - http-outgoing-0 << "Date: Thu, 05 Dec 2024 22:41:54 GMT[\r][\n]"
2024-12-05 14:41:53 [main] DEBUG org.apache.http.wire:73 - http-outgoing-0 << "x-amz-transition-default-minimum-object-size: all_storage_classes_128K[\r][\n]"
2024-12-05 14:41:53 [main] DEBUG org.apache.http.wire:73 - http-outgoing-0 << "Content-Length: 284[\r][\n]"
2024-12-05 14:41:53 [main] DEBUG org.apache.http.wire:73 - http-outgoing-0 << "Server: AmazonS3[\r][\n]"
2024-12-05 14:41:53 [main] DEBUG org.apache.http.wire:73 - http-outgoing-0 << "[\r][\n]"
2024-12-05 14:41:53 [main] DEBUG org.apache.http.wire:73 - http-outgoing-0 << "<?xml version="1.0" encoding="UTF-8"?>[\n]"
2024-12-05 14:41:53 [main] DEBUG org.apache.http.wire:87 - http-outgoing-0 << "<LifecycleConfiguration xmlns="http://s3.amazonaws.com/doc/2006-03-01/"><Rule><ID>testglacierrule</ID><Filter/><Status>Enabled</Status><Transition><Days>0</Days><StorageClass>GLACIER_IR</StorageClass></Transition></Rule></LifecycleConfiguration>"
2024-12-05 14:41:53 [main] DEBUG software.amazon.awssdk.requestId:85 - Received successful response: 200, Request ID: BP29JKDRGSNK6B6K, Extended Request ID: OutiawFhABSRYd4bvByXvJsPSgBah9llKmiukhRgBIO2KtsXJZcmO/nEEv7cbhU1LVI5z+Zf2Jg=
2024-12-05 14:41:53 [main] DEBUG software.amazon.awssdk.request:85 - Received successful response: 200, Request ID: BP29JKDRGSNK6B6K, Extended Request ID: OutiawFhABSRYd4bvByXvJsPSgBah9llKmiukhRgBIO2KtsXJZcmO/nEEv7cbhU1LVI5z+Zf2Jg=
...
...
2024-12-05 14:43:39 [main] DEBUG software.amazon.awssdk.http.auth.aws.internal.signer.DefaultV4RequestSigner:85 - AWS4 Canonical Request: PUT
/
lifecycle=
amz-sdk-invocation-id:7f98dc13-0bac-84b3-4241-71afb3b38f83
amz-sdk-request:attempt=1; max=4
content-length:291
content-md5:BCSaAQ3SB2V/04LndsUt8g==
content-type:application/xml
host:testbucket-issue1880.s3.us-east-2.amazonaws.com
x-amz-content-sha256:UNSIGNED-PAYLOAD
x-amz-date:20241205T224339Z
...
...
2024-12-05 14:43:39 [main] DEBUG org.apache.http.wire:73 - http-outgoing-1 >> "PUT /?lifecycle HTTP/1.1[\r][\n]"
2024-12-05 14:43:39 [main] DEBUG org.apache.http.wire:73 - http-outgoing-1 >> "Host: testbucket-issue1880.s3.us-east-2.amazonaws.com[\r][\n]"
2024-12-05 14:43:39 [main] DEBUG org.apache.http.wire:73 - http-outgoing-1 >> "amz-sdk-invocation-id: 7f98dc13-0bac-84b3-4241-71afb3b38f83[\r][\n]"
2024-12-05 14:43:39 [main] DEBUG org.apache.http.wire:73 - http-outgoing-1 >> "amz-sdk-request: attempt=1; max=4[\r][\n]"
...
2024-12-05 14:43:39 [main] DEBUG org.apache.http.wire:73 - http-outgoing-1 >> "Content-Length: 291[\r][\n]"
2024-12-05 14:43:39 [main] DEBUG org.apache.http.wire:73 - http-outgoing-1 >> "Connection: Keep-Alive[\r][\n]"
2024-12-05 14:43:39 [main] DEBUG org.apache.http.wire:73 - http-outgoing-1 >> "Expect: 100-continue[\r][\n]"
2024-12-05 14:43:39 [main] DEBUG org.apache.http.wire:73 - http-outgoing-1 >> "[\r][\n]"
2024-12-05 14:43:39 [main] DEBUG org.apache.http.wire:73 - http-outgoing-1 << "HTTP/1.1 100 Continue[\r][\n]"
2024-12-05 14:43:39 [main] DEBUG org.apache.http.wire:73 - http-outgoing-1 << "[\r][\n]"
2024-12-05 14:43:39 [main] DEBUG org.apache.http.wire:87 - http-outgoing-1 >> "<?xml version="1.0" encoding="UTF-8"?><LifecycleConfiguration xmlns="http://s3.amazonaws.com/doc/2006-03-01/"><Rule><ID>testglacierrule</ID><Filter></Filter><Status>Enabled</Status><Transition><Days>0</Days><StorageClass>GLACIER_IR</StorageClass></Transition></Rule></LifecycleConfiguration>"
2024-12-05 14:43:40 [main] DEBUG org.apache.http.wire:73 - http-outgoing-1 << "HTTP/1.1 200 OK[\r][\n]"
2024-12-05 14:43:40 [main] DEBUG org.apache.http.wire:73 - http-outgoing-1 << "x-amz-id-2: 4qz4VUu2csoeosSXmHnAq3HGNHQsvLDnT0CXK4tRAtHqUHIZOiF5QFlt1MznUfFX4YERpUahh8k=[\r][\n]"
2024-12-05 14:43:40 [main] DEBUG org.apache.http.wire:73 - http-outgoing-1 << "x-amz-request-id: 1N6VAJH10MXV91P2[\r][\n]"
2024-12-05 14:43:40 [main] DEBUG org.apache.http.wire:73 - http-outgoing-1 << "Date: Thu, 05 Dec 2024 22:43:40 GMT[\r][\n]"
2024-12-05 14:43:40 [main] DEBUG org.apache.http.wire:73 - http-outgoing-1 << "x-amz-transition-default-minimum-object-size: all_storage_classes_128K[\r][\n]"
2024-12-05 14:43:40 [main] DEBUG org.apache.http.wire:73 - http-outgoing-1 << "Content-Length: 0[\r][\n]"
2024-12-05 14:43:40 [main] DEBUG org.apache.http.wire:73 - http-outgoing-1 << "Server: AmazonS3[\r][\n]"
2024-12-05 14:43:40 [main] DEBUG org.apache.http.wire:73 - http-outgoing-1 << "[\r][\n]"
2024-12-05 14:43:40 [main] DEBUG software.amazon.awssdk.requestId:85 - Received successful response: 200, Request ID: 1N6VAJH10MXV91P2, Extended Request ID: 4qz4VUu2csoeosSXmHnAq3HGNHQsvLDnT0CXK4tRAtHqUHIZOiF5QFlt1MznUfFX4YERpUahh8k=
...

Java SDK is sending below request body while invoking PutBucketLifecycleConfiguration configuration:

<?xml version="1.0" encoding="UTF-8"?>
<LifecycleConfiguration xmlns="http://s3.amazonaws.com/doc/2006-03-01/">
    <Rule>
        <ID>testglacierrule</ID>
        <Filter></Filter>
        <Status>Enabled</Status>
        <Transition>
            <Days>0</Days>
            <StorageClass>GLACIER_IR</StorageClass>
        </Transition>
    </Rule>
</LifecycleConfiguration>

AWS Tools for PowerShell uses AWS SDK for .NET behind the scenes. Using AWS .NET SDK code below:

using Amazon.S3.Model;
using System.Net;
using System.Text;

string bucketName = "<<bucket-name>>";

Amazon.AWSConfigs.LoggingConfig.LogResponses = Amazon.ResponseLoggingOption.Always;
Amazon.AWSConfigs.LoggingConfig.LogTo = Amazon.LoggingOptions.Console;
Amazon.AWSConfigs.LoggingConfig.LogMetrics = true;
Amazon.AWSConfigs.AddTraceListener("Amazon", new System.Diagnostics.ConsoleTraceListener());

using (AmazonS3Client amazonS3Client = new AmazonS3Client(RegionEndpoint.USEast2))
{
    var getbucketLifecycleConfig = await amazonS3Client.GetLifecycleConfigurationAsync(new GetLifecycleConfigurationRequest()
    {
        BucketName = bucketName,
    });

    var putbucketLifecycleConfig = await amazonS3Client.PutLifecycleConfigurationAsync(new PutLifecycleConfigurationRequest()
    {
        BucketName = bucketName,
        Configuration = new LifecycleConfiguration() { Rules = getbucketLifecycleConfig.Configuration.Rules }
    });
}

Send the following request to AWS S3 service (captured using network monitoring tool):

PUT https://testbucket-issue1880.s3.us-east-2.amazonaws.com/?lifecycle HTTP/1.1
User-Agent: aws-sdk-dotnet-coreclr/3.7.404.4 ua/2.0 os/windows#10.0.19045.0 md/ARCH#X64 lang/.NET_Core#6.0.36 md/aws-sdk-dotnet-core#3.7.400.32 api/S3#3.7.404.4 cfg/retry-mode#legacy md/ClientAsync cfg/init-coll#1
amz-sdk-invocation-id: 008c8295-a3dd-416b-89ee-055a6f5e8d25
amz-sdk-request: attempt=1; max=5
x-amz-security-token: REDACTED
Host: testbucket-issue1880.s3.us-east-2.amazonaws.com
X-Amz-Date: 20241205T230738Z
X-Amz-Content-SHA256: d51b68405dbfc374ccf1575f63ab69270c8c628556316800c041926256929ada
Authorization: AWS4-HMAC-SHA256 Credential=REDACTED/20241205/us-east-2/s3/aws4_request, SignedHeaders=content-md5;content-type;host;user-agent;x-amz-content-sha256;x-amz-date;x-amz-security-token, Signature=REDACTED
Content-Length: 236
Content-Type: application/xml
Content-MD5: 6rt3TVMgoVszzs7m1ca+6w==

<LifecycleConfiguration xmlns="http://s3.amazonaws.com/doc/2006-03-01/"><Rule><Transition><Days>0</Days><StorageClass>GLACIER_IR</StorageClass></Transition><ID>testglacierrule</ID><Status>Enabled</Status></Rule></LifecycleConfiguration>

It is not sending empty <FILTER/> element and it fails.

Analysis:

For customer's scenario, the PutBucketLifecycleConfiguration somehow expects empty <Filter /> element at least in request body. Even though LifecycleRule page mentions that Filter is optional, it also states that Filter is required if the LifecycleRule does not contain a Prefix element. This could be the reason why we received error The XML you provided was not well-formed or did not validate against our published schema from the S3 service.

@AaronStarr-pga As a workaround, you would need to parse response from Get-S3LifecycleConfiguration to see if Filter property is null and then set it to empty collection if that is the case. As a general guideline, it is also recommended to use Prefix at LifecycleRule level to optimize costs. If you are using Prefix then this issue should not occur since Filter is only required if Prefix is absent.

Just FYI, the handling of processing empty elements by AWS SDK .NET unmarshaller would be fixed in next major version v4 (currently in preview).

Thanks,
Ashish

@ashishdhingra ashishdhingra added needs-review response-requested Waiting on additional info and feedback. Will move to "closing-soon" in 7 days. and removed investigating This issue is being investigated and/or work is in progress to resolve the issue. needs-review labels Dec 6, 2024
@AaronStarr-pga
Copy link
Author

Thank you for the investigation Ashish and additional information, I have incorporated the workaround in my code.

@ashishdhingra
Copy link
Contributor

Thank you for the investigation Ashish and additional information, I have incorporated the workaround in my code.

@AaronStarr-pga Thanks. I will close this issue for now since the fix is already in place in AWS .NET SDK v4-development branch.

Copy link

github-actions bot commented Dec 9, 2024

⚠️COMMENT VISIBILITY WARNING⚠️

Comments on closed issues are hard for our team to see.
If you need more assistance, please either tag a team member or open a new issue that references this one.
If you wish to keep having a conversation with other community members under this issue feel free to do so.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
bug This issue is a bug. module/powershell-cmdlets p2 This is a standard priority issue response-requested Waiting on additional info and feedback. Will move to "closing-soon" in 7 days.
Projects
None yet
Development

No branches or pull requests

2 participants