Skip to content

s3: Specifying e_tags in DeleteObjects operation results in MalformedXML error #1311

Open

Description

@Fuuzetsu

Describe the bug

If I uncomment set_etag below

let Ok(oi) = aws_sdk_s3::types::ObjectIdentifier::builder()
                .key(key)
                // .set_e_tag(object.e_tag)
                .build()
            else {
                continue;
            };

Then using this ObjectIdentifier as part of Delete results in

code: "MalformedXML", message: "The XML you provided was not well-formed or did not validate against our published schema",

Regression Issue

  • Select this option if this issue appears to be a regression.

Expected Behavior

It should work.

Current Behavior

Malformed XML error

Reproduction Steps

Just make any DeleteObjects with E-Tag being populated. I'm deleting 1000 objects at a time.

See https://github.com/Fuuzetsu/aws-delete-objects-etag-repro

Possible Solution

No response

Additional Information/Context

No response

Version

aws-sdk-s3 = "1.90.0"

Environment details (OS name and version, etc.)

Linux

Logs

even with trace level the request body is not visible so logs aren't very useful

Activity

  1. added
    bugThis issue is a bug.
    needs-triageThis issue or PR still needs to be triaged.
    on Jun 19, 2025
  2. landonxjames commented on Jun 19, 2025

    @landonxjames
    Contributor

    Does this happen with any E-Tag value? Wondering if somehow an unexpected XML token is showing up in the E-Tag and confusing the parser.

  3. Fuuzetsu commented on Jun 20, 2025

    @Fuuzetsu
    Author

    I made a reproducer here: https://github.com/Fuuzetsu/aws-delete-objects-etag-repro

    You can see the output in README.md there. While there, I was wondering if I can delete an object with etag with the DeleteObject API via If-Match like described at https://docs.aws.amazon.com/AmazonS3/latest/API/API_DeleteObject.html#API_DeleteObject_RequestSyntax but that doesn't work either. Not sure if that's a separate issue or not.

    I noticed that the ETag from the list operation came in with double quotes around it. Stripping it didn't help. Sending an ETag that was just foo also didn't help.

    You can see in the output that I can delete the object just fine if I don't pass the ETag.

    Let me know if you need more info.

  4. Fuuzetsu commented on Jun 20, 2025

    @Fuuzetsu
    Author

    For the DeleteObject, we can see some of the request in the trace logs. Not sure if it's useful but I include that bit below. One can run the reproducer with RUST_LOG=trace and see everything.

    2025-06-20T00:16:08.110198Z TRACE S3.DeleteObject{rpc.service="S3" rpc.method="DeleteObject" sdk_invocation_id=8125830 rpc.system="aws-api"}:try_op:try_attempt{attempt=1}: aws_sigv4::http_request::sign: signing request request=SignableRequest { method: "DELETE", uri: https://tsuru-scratch.s3.ap-northeast-1.amazonaws.com/private/fuuzetsu/etag-delete-repro?x-id=DeleteObject, headers: [("if-match", "\"d41d8cd98f00b204e9800998ecf8427e\""), ("user-agent", "aws-sdk-rust/1.3.7 os/linux lang/rust/1.87.0"), ("x-amz-user-agent", "aws-sdk-rust/1.3.7 ua/2.1 api/s3/1.93.0 os/linux lang/rust/1.87.0 m/E md/http#hyper-1.x")], body: Bytes("** REDACTED **. To print 0 bytes of raw data, set environment variable `LOG_SIGNABLE_BODY=true`") } params=V4(SigningParams { identity: Identity { data: Credentials { provider_name: "ProfileFile", access_key_id: "AKIA37CMHUG2J657FM2A", secret_access_key: "** redacted **", expires_after: "never" }, expiration: None }, region: "ap-northeast-1", name: "s3", time: SystemTime { tv_sec: 1750378568, tv_nsec: 110194920 }, settings: SigningSettings { percent_encoding_mode: Single, payload_checksum_kind: XAmzSha256, signature_location: Headers, expires_in: None, excluded_headers: Some(["authorization", "user-agent", "x-amzn-trace-id", "transfer-encoding"]), uri_path_normalization_mode: Disabled, session_token_mode: Include, session_token_name_override: None } })
    2025-06-20T00:16:08.110232Z TRACE S3.DeleteObject{rpc.service="S3" rpc.method="DeleteObject" sdk_invocation_id=8125830 rpc.system="aws-api"}:try_op:try_attempt{attempt=1}: aws_sigv4::http_request::sign: canonical_request=DELETE
    /private/fuuzetsu/etag-delete-repro
    x-id=DeleteObject
    host:tsuru-scratch.s3.ap-northeast-1.amazonaws.com
    if-match:"d41d8cd98f00b204e9800998ecf8427e"
    x-amz-content-sha256:e3b0c44298fc1c149afbf4c8996fb92427ae41e4649b934ca495991b7852b855
    x-amz-date:20250620T001608Z
    x-amz-user-agent:aws-sdk-rust/1.3.7 ua/2.1 api/s3/1.93.0 os/linux lang/rust/1.87.0 m/E md/http#hyper-1.x
    
    host;if-match;x-amz-content-sha256;x-amz-date;x-amz-user-agent
    e3b0c44298fc1c149afbf4c8996fb92427ae41e4649b934ca495991b7852b855
    2025-06-20T00:16:08.110248Z TRACE S3.DeleteObject{rpc.service="S3" rpc.method="DeleteObject" sdk_invocation_id=8125830 rpc.system="aws-api"}:try_op:try_attempt{attempt=1}: aws_smithy_runtime::client::interceptors: running `read_after_signing` interceptors
    2025-06-20T00:16:08.110252Z TRACE S3.DeleteObject{rpc.service="S3" rpc.method="DeleteObject" sdk_invocation_id=8125830 rpc.system="aws-api"}:try_op:try_attempt{attempt=1}: aws_smithy_runtime::client::interceptors: running `modify_before_transmit` interceptors
    2025-06-20T00:16:08.110264Z TRACE S3.DeleteObject{rpc.service="S3" rpc.method="DeleteObject" sdk_invocation_id=8125830 rpc.system="aws-api"}:try_op:try_attempt{attempt=1}: aws_smithy_runtime::client::stalled_stream_protection: skipping stalled stream protection for zero length request body
    2025-06-20T00:16:08.110266Z TRACE S3.DeleteObject{rpc.service="S3" rpc.method="DeleteObject" sdk_invocation_id=8125830 rpc.system="aws-api"}:try_op:try_attempt{attempt=1}: aws_smithy_runtime::client::interceptors: running `read_before_transmit` interceptors
    2025-06-20T00:16:08.110269Z DEBUG S3.DeleteObject{rpc.service="S3" rpc.method="DeleteObject" sdk_invocation_id=8125830 rpc.system="aws-api"}:try_op:try_attempt{attempt=1}: aws_smithy_runtime_api::client::interceptors::context: entering 'transmit' phase
    2025-06-20T00:16:08.110272Z TRACE S3.DeleteObject{rpc.service="S3" rpc.method="DeleteObject" sdk_invocation_id=8125830 rpc.system="aws-api"}:try_op:try_attempt{attempt=1}: aws_smithy_runtime::client::orchestrator: transmitting request request=Request { body: SdkBody { inner: Once(Some(b"")), retryable: true }, uri: Uri { as_string: "https://tsuru-scratch.s3.ap-northeast-1.amazonaws.com/private/fuuzetsu/etag-delete-repro?x-id=DeleteObject", parsed: H0(https://tsuru-scratch.s3.ap-northeast-1.amazonaws.com/private/fuuzetsu/etag-delete-repro?x-id=DeleteObject) }, method: DELETE, extensions: Extensions { extensions_02x: Extensions, extensions_1x: Extensions }, headers: Headers { headers: {"if-match": HeaderValue { _private: H0("\"d41d8cd98f00b204e9800998ecf8427e\"") }, "user-agent": HeaderValue { _private: H0("aws-sdk-rust/1.3.7 os/linux lang/rust/1.87.0") }, "x-amz-user-agent": HeaderValue { _private: H0("aws-sdk-rust/1.3.7 ua/2.1 api/s3/1.93.0 os/linux lang/rust/1.87.0 m/E md/http#hyper-1.x") }, "x-amz-date": HeaderValue { _private: H0("20250620T001608Z") }, "authorization": HeaderValue { _private: H0("AWS4-HMAC-SHA256 Credential=AKIA37CMHUG2J657FM2A/20250620/ap-northeast-1/s3/aws4_request, SignedHeaders=host;if-match;x-amz-content-sha256;x-amz-date;x-amz-user-agent, Signature=652f1f974db3cf0b8d6a8169e75260feba1b3c6d13e194869606345b0ed74e6d") }, "x-amz-content-sha256": HeaderValue { _private: H0("e3b0c44298fc1c149afbf4c8996fb92427ae41e4649b934ca495991b7852b855") }, "amz-sdk-request": HeaderValue { _private: H0("attempt=1; max=3") }, "amz-sdk-invocation-id": HeaderValue { _private: H0("0165f1b3-f30d-4396-aa47-7d07f623bade") }} } }
    
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Metadata

Metadata

Assignees

No one assigned

    Labels

    bugThis issue is a bug.

    Type

    No type

    Projects

    No projects

      Milestone

      No milestone

      Relationships

      None yet

      Development

      No branches or pull requests

      Issue actions