I'm currently using the latest version of the aws-sdk-js. I have found what I think is a bug relating to uploading objects to an S3 bucket using the pre-signed URLs. If I create an object using the SDK like so:
const params = { Bucket, Key: 'testfile', Metadata, Body: "This is a test object", Tagging: 'sem=somethingSemantic' };
s3.putObject(params, (err, data) => {
if (err) {
console.log('s3 error: ', err);
}
console.log('it worked: ', data);
}
This works, I see an object called testfile appear in my bucket and it has a tag sem: somethingSemantic.
However, when I try to generate a url using the following code:
s3.getSignedUrl('putObject', { Bucket, Key: 'testfile', Metadata, Tagging: 'sem=somethingSemantic' Expires: 1800 }, (error, url) => {
if (error) {
console.log('s3 error: ', error);
}
console.log('The URL is', url);
}
This code generates a URL similar to the following: https://bucketname.s3.amazonaws.com/testfile?AWSAccessKeyId=mykey&Expires=1484777697&Signature=signatureString&x-amz-tagging=sem%3DsomethingSemantic
When I do a put on this URL using postman and upload the binary file, it creates the file correctly, however it does NOT create the tag. Even more curious is the fact that if I take out the x-amz-tagging part of the pre-signed URL and manually input the header into postman, like so:

Everything works fine. Can someone verify if this is actually a bug or if something else is going on here?
UPDATE: I ran the pre-signed URL in curl as well to verify this is not a postman issue, same behavior with curl, no tagging via pre-signed URLs.
@Suiname
This appears to be an issue on S3's side, but I've reached out to them to be sure. I'll respond back once I get a response.
@chrisradek Thanks, I appreciate it
@chrisradek Any update on this? We are blocked from integrating S3 until this gets fixed.
@Suiname
Sorry, I haven't gotten a response yet from the S3 team. It might help if you post the same question to the S3 forums. If you do, post a link back here and I'll forward the link as well.
Here's my S3 forum thread: https://forums.aws.amazon.com/thread.jspa?threadID=247687
@chrisradek I assume there hasn't been an update on this? They asked me to create a support request, but unfortunately my AWS account doesn't allow for that.
@Suiname
I know they're looking into it, but I don't know what their final resolution will be. Anyone else that also needs this functionality should respond to the forum thread to let S3 know they want this feature. I'll update when I hear something new as well.
+1 . Being able to add tags via presigned URL is a must-have.
@s2maki As a work-around, tagging is supported for direct-from-browser uploads via the S3 PostObject API. You can create a policy document for a POST upload with AWS.S3.createPresignedPost.
I'll give that a try, thanks!
The PostObject API does not meet our requirements. Only browsers that support XHRv2 can do ajax multipart posts. Using a presigned PUT request allows us to support XHRv1 clients because the params are part of the URL.
Dear AWS, please fix this bug!
@dustMason I've passed your feedback on to the S3 team internally. The best way to reach out to them directly is via the S3 AWS developer forum, as they do not monitor any SDK's issue queue.
Anyone got an update on this? Or a URL to the forum post where S3 have replied?
You also need to include the 'x-amz-tagging' header as a part of the actual PUT/POST request. Hope this helps!
Has anyone found a solution for this?
EDIT: My issue ended up being insufficient permissions to add tags to objects. After adding the necessary putObjectTagging permissions, adding the headers to the actual PUT request worked perfectly.
There is something weird going on. It seems that when signing the url you must set just some random tag with it but you actually set real tags within the PUT operation.
Here's my signing code:
var signedURL = s3.getSignedUrl("putObject", {
Bucket: "mybucket",
Key: "foobar.pdf",
ContentType: "application/pdf",
ACL: "public-read",
Tagging: "foo=anything",
});
And here's browser upload code
const headers = new Headers();
headers.append("x-amz-tagging", "myrealtag=tagvalue");
const res = await fetch(signedURL, {
method: "PUT",
body: file,
headers,
});
@epeli That's interesting. Maybe the signature just checks whether or not a tag is set as a boolean or something and not the actual tag content. EDIT: That fixes the problem if you're doing the upload through code like you showed, but for the use case where I want to just give the client the pre-signed URL link and they perform the upload via a browser themselves, this doesn't solve the problem because the URL params don't set the header tags properly.
I observed the same behavior. Tagging does not happen (put operation succeeds but no tag). I have putObjectTagging permission.
@Suiname
This is currently working. Are you able to get this working with the latest version of the SDK?
This issue has been automatically closed because there has been no response to our request for more information from the original author. With only the information that is currently in the issue, we don't have enough information to take action. Please reach out if you have or find the answers we need so that we can investigate further.
Hey @epeli, re:
There is something weird going on. It seems that when signing the url you must set just some random tag with it but you actually set real tags within the PUT operation.
Here's my signing code:
var signedURL = s3.getSignedUrl("putObject", { Bucket: "mybucket", Key: "foobar.pdf", ContentType: "application/pdf", ACL: "public-read", Tagging: "foo=anything", });And here's browser upload code
const headers = new Headers(); headers.append("x-amz-tagging", "myrealtag=tagvalue"); const res = await fetch(signedURL, { method: "PUT", body: file, headers, });
I had the exact same issue and was banging my head against a brick wall, but then I realized the current documentation notes that some params are not processed, including Tagging: https://docs.aws.amazon.com/AWSJavaScriptSDK/latest/AWS/S3.html#getSignedUrl-property. They need to be passed as headers, e.g. x-amz-tagging=mytagkey%3Dmytagvalue.
Regardless, I don't see why this issue dies in December last year without someone from AWS mentioning this fact?
Note: Not all operation parameters are supported when using pre-signed URLs. Certain parameters, such as SSECustomerKey, ACL, Expires, ContentLength, or Tagging must be provided as headers when sending a request. If you are using pre-signed URLs to upload from a browser and need to use these fields, see createPresignedPost().
This thread has been automatically locked since there has not been any recent activity after it was closed. Please open a new issue for related bugs and link to relevant comments in this thread.
Most helpful comment
You also need to include the 'x-amz-tagging' header as a part of the actual PUT/POST request. Hope this helps!