I ran into the same problem when using S3.getSignedUrl('putObject' , serveride, and then tried to use this client url.
What I noticed in my case, which may be relevant to yours, is that signatures created with all S3.getSignedUrl take into account request headers. Therefore, if you create a URL, it will crash with the same error message you received if not sent with the same headers.
One example of a failure: Generated as follows.
var params = { Bucket: 'YourBucket', Key: 'uniqueFileKey', Expires: 10000 }; s3.getSignedUrl('putObject', params, function (err, url) { if(err){ return cb(err); } return cb(null, url) });
The following request fails when using the same URL. This request was made from a browser.
RequestMethod: Put Headers: { Accept:*
And the difference is that the created signature does not contain the content type, where the request sets the content type. Params need to match the headers, or the error that you choose will not match the signature.
Successful example below:
var params = { Bucket: 'YourBucket', Key: 'uniqueFileKey', Expires: 10000, Content-Type: 'application/x-www-form-urlencoded; charset=UTF-8' }; s3.getSignedUrl('putObject', params, function (err, url) { if(err){ return cb(err); } return cb(null, url) });