Im trying do do a HEAD Object request to the S3 REST API but I keep getting a 403 Forbidden error, even though I have the policy setup with the necessary permissions on S3.
It still could be your signature, and I suspect that it is, for the following reasons:
Your observation that the message body is a good observation; however, it doesn't mean what you have concluded it means.
The lack of a response body does not give you any information at all about the nature of the error, in this case, because a web server is not supposed to return a body along with a HEAD
response, no matter what:
The
HEAD
method is identical toGET
except that the serverMUST NOT
return a message-body in the response— http://www.w3.org/Protocols/rfc2616/rfc2616-sec9.html (RFC-2616)
Testing this on my side, I've confirmed that S3's response to an unsigned HEAD
request and to an incorrectly-signed HEAD
request is no different: it's always HTTP/1.1 403 Forbidden
with no message body.
Note, also, that a signed URL for GET
is not valid for HEAD
, and vice versa.
In both S3 Signature Version 2 and S3 Signature Version 4, the "String to Sign" includes the "HTTP Verb," which would be GET
or HEAD
, meaning that a signature that's valid for GET
would not be valid for HEAD
, and vice versa... the request method must be known at the time of signing, because it's an element that's used in the signing process.
The s3:GetObject
permission is the only documented permission required for using HEAD
, which seems to eliminate permissions as the problem, if GET
is working, which points back to the signature as the potential issue.
Had the same issue but with a different root cause - was trying to create a bucket, and instead of getting a 404, got 403. As S3 is globally namespaced, someone else had created the bucket, so while I had the correct permissions and setup for my account, I still would get 403 from a HEAD request. Solution was to check if the bucket exists globally first, and if so, try a different bucket name.
Additional comment on @Michael-sqlbot 's answer above ...
I faced the identical symptoms but I had a different root cause.
If you are trying to HEAD a file which does not exist, then this will also return a 403-forbidden error, UNLESS you have the s3:ListBucket permission.
In my case, I had the s3.GetObject, s3.PutObject, and s3.HeadBucket permissions, but it wasn't until I added s3.ListBucket that I got the correct 404 - not found error.
This is also explained here: https://aws.amazon.com/premiumsupport/knowledge-center/s3-rest-api-cloudfront-error-403/
Confirmed that HEAD a presigned-URL will get 403 Forbidden. If set custom headers such as content-type of the object. The 403 response will not contain the custom header and still get application/xml.