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

S3: PutObject operation with empty body fails with 501 "NotImplemented" error #1583

Closed
3 tasks done
gdavison opened this issue Feb 8, 2022 · 10 comments
Closed
3 tasks done
Labels
bug This issue is a bug. pending-release This issue will be fixed by an approved PR that hasn't been released yet.

Comments

@gdavison
Copy link
Contributor

gdavison commented Feb 8, 2022

Documentation

Describe the bug

When the PutObject operation is called with an empty body, the request fails with the following error:

operation error S3: PutObject, https response error StatusCode: 501, RequestID: ********, HostID: *********, api error NotImplemented: A header you provided implies functionality that is not implemented

Expected behavior

The request should have succeeded

Current behavior

The request fails

2022-02-07T17:02:05.140-0800 [DEBUG] [aws-sdk-go-v2] Request
PUT /testState?x-id=PutObject HTTP/1.1
Host: ****.s3.us-east-1.amazonaws.com
User-Agent: aws-sdk-go-v2/1.13.0 os/macos lang/go/1.17.2 md/GOOS/darwin md/GOARCH/amd64 api/s3/1.24.1
Content-Length: 0
Accept-Encoding: identity
Amz-Sdk-Invocation-Id: d216ba6d-9c6b-44c9-94ff-7047063fe9a9
Amz-Sdk-Request: attempt=1; max=5
Authorization: AWS4-HMAC-SHA256 Credential=********/20220208/us-east-1/s3/aws4_request, SignedHeaders=accept-encoding;amz-sdk-invocation-id;amz-sdk-request;content-type;host;x-amz-content-sha256;x-amz-date;x-amz-security-token, Signature=9ae6f636bb39f3e475890ab1f26994020de91dcbba6105c11a4d1c7413936fb8
Content-Type: application/json
X-Amz-Content-Sha256: UNSIGNED-PAYLOAD
X-Amz-Date: 20220208T010205Z
X-Amz-Security-Token: ********

2022-02-07T17:02:05.512-0800 [DEBUG] [aws-sdk-go-v2] Response
HTTP/1.1 501 Not Implemented
Connection: close
Transfer-Encoding: chunked
Content-Type: application/xml
Date: Tue, 08 Feb 2022 01:02:04 GMT
Server: AmazonS3
X-Amz-Id-2: fhvvo1UE+UoJzAovIbsaH0cJ5N1CN/Cgy04330ogHcbGuOOVfSP5DhT7VhqEaNMNkrRZaJgrcmI=
X-Amz-Request-Id: D8Y4RJ014M60HTPE

14d
<?xml version="1.0" encoding="UTF-8"?>
<Error><Code>NotImplemented</Code><Message>A header you provided implies functionality that is not implemented</Message><Header>Transfer-Encoding</Header><RequestId>D8Y4RJ014M60HTPE</RequestId><HostId>fhvvo1UE+UoJzAovIbsaH0cJ5N1CN/Cgy04330ogHcbGuOOVfSP5DhT7VhqEaNMNkrRZaJgrcmI=</HostId></Error>
0

Steps to Reproduce

data := []byte{}

i := &s3.PutObjectInput{
	ContentType:          aws.String("application/json"),
	Body:                 bytes.NewReader(data),
	Bucket:               aws.String("test"),
	Key:                  aws.String("path"),
	ServerSideEncryption: "AES256",
}

ctx := context.Background()
_, err := c.s3Client.PutObject(ctx, i)

Possible Solution

No response

AWS Go SDK version used

github.com/aws/aws-sdk-go-v2 v1.13.0, github.com/aws/aws-sdk-go-v2/service/s3 v1.24.1

Compiler and Version used

go version go1.17.2 darwin/amd64

Operating System and version

macOS 10.15.7

@gdavison gdavison added bug This issue is a bug. needs-triage This issue or PR still needs to be triaged. labels Feb 8, 2022
@jasdel
Copy link
Contributor

jasdel commented Feb 25, 2022

Thanks for reporting this issue @gdavison I've been able to reproduce this issue locally with the v2 SDK, and have begun investigating why this is happening. It doesn't look like this issue occurs with the v1 SDK. Even though the SDK is able to derive the Content-Length: 0 of the request, something is preventing that from being serialized in the HTTP request message sent, causing the HTTP client to use Transfer-encoding: chunked.

Did you discover this as a new bug when updating the SDK to a new version?

@jasdel jasdel added investigating This issue is being investigated and/or work is in progress to resolve the issue. and removed needs-triage This issue or PR still needs to be triaged. labels Feb 25, 2022
jasdel added a commit to aws/smithy-go that referenced this issue Feb 25, 2022
Updates the smithy-go HTTP Request to correctly handle building the
request to an http.Request. HTTP Client Request must not have a non-nil
Body if the ContentLength is 0. The client will treat this case as
unknown length and use "transfer-encoding": chunked. This breaks Amazon
S3 operations like PutObject which require content-length and do not
support "transfer-encoding: chunked"

Related to aws/aws-sdk-go-v2#1583
jasdel added a commit to aws/smithy-go that referenced this issue Feb 25, 2022
Updates the smithy-go HTTP Request to correctly handle building the
request to an http.Request. HTTP Client Request must not have a non-nil
Body if the ContentLength is 0. The client will treat this case as
unknown length and use "transfer-encoding": chunked. This breaks Amazon
S3 operations like PutObject which require content-length and do not
support "transfer-encoding: chunked"

Related to aws/aws-sdk-go-v2#1583
@jasdel
Copy link
Contributor

jasdel commented Feb 25, 2022

I've created PR aws/smithy-go#356 in the smithy-go repo that addresses this issue. You can work around this issue until this changed is merged by running the following command to update your go.mod to point to refer to the PR change:

go get github.com/aws/smithy-go@v1.11.1-0.20220225220832-6630cb6f6e84)

@jasdel jasdel added pending-release This issue will be fixed by an approved PR that hasn't been released yet. and removed investigating This issue is being investigated and/or work is in progress to resolve the issue. labels Feb 25, 2022
jasdel added a commit to aws/smithy-go that referenced this issue Feb 25, 2022
Updates the smithy-go HTTP Request to correctly handle building the
request to an http.Request. HTTP Client Request must not have a non-nil
Body if the ContentLength is 0. The client will treat this case as
unknown length and use "transfer-encoding": chunked. This breaks Amazon
S3 operations like PutObject which require content-length and do not
support "transfer-encoding: chunked"

Related to aws/aws-sdk-go-v2#1583
@jasdel
Copy link
Contributor

jasdel commented Mar 7, 2022

This issue has been resolved in the SDK's smithy-go dependency. The SDK's next release will include this fix.

@jasdel jasdel closed this as completed Mar 7, 2022
@github-actions
Copy link

github-actions bot commented Mar 7, 2022

⚠️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.

@lestephane
Copy link

@jasdel I added

replace github.com/aws/smithy-go v1.11.1 => github.com/aws/smithy-go v1.11.1-0.20220225220832-6630cb6f6e84

to my .mod file, and the problem is still there.

In my case:

  • the ContentLength in the PutObjectInput is set by me explcitly, to 0.
  • the Request log shows that no Content-Length header is sent to the s3 endpoint.

@jasdel
Copy link
Contributor

jasdel commented Mar 14, 2022

@lestephane are you still experiencing this issue after updating to the latest version of S3, github.com/aws/aws-sdk-go-v2/service/s3@v1.26.0 This should also update your application to depend on github.com/aws/smithy-go@1.11.1.

Setting ContentLength to 0 should be OK. What type of value are you using for the Body member?

@lestephane
Copy link

@jasdel I was using 1.26.0 and 1.11.1 when I got the problem and landed upon this issue in GitHub.
Then replaced smithy 1.11.1 with 1.11.1-..., and still got the issue.

I'm using a *Reader as Body.

@lestephane
Copy link

Would passing no Body when the ContentLength is 0 be an workaround? I was trying to avoid conditionals, as I'm getting the length and the reader from another library...

@jasdel
Copy link
Contributor

jasdel commented Mar 15, 2022

Thanks for the update. You should be able to provide an reader that matches the content length. Though its important to note, if the ContentLength is 0 and the value of Body is an io.Reader that is unseekable the SDK won't know that you intended to send no payload. In this case it probably is best to leave Body nil if ContentLength is 0, or use a value for Body that is seekable or implements a Len() int method.

The reason the SDK is not using your provided ContentLength of 0, is because ContentLength member is not apointer. The SDK has no way to know that you set ContentLength to 0 vs that is the member's initialized zero value. If ContentLength is a non-zero value then the SDK will use it. Otherwise the SDK will attempt to determine the length of the payload from the Body value.

@lestephane
Copy link

I will try to not specify any Body when I have time, and report. Hopefully that does the trick.

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. pending-release This issue will be fixed by an approved PR that hasn't been released yet.
Projects
None yet
Development

No branches or pull requests

3 participants