Reputation: 91
I'm aware there are other threads on here about this issue but am still struggling to find the right solution. I am attempting to download a set of specific objects within an S3 bucket (that I do have access to) using the following python script. When running the script, the first object successfully downloads but then this error (403) is thrown:
botocore.exceptions.ClientError: An error occurred (403) when calling the HeadObject operation: Forbidden
See below my code:
import csv
import boto3
import re
import logging
from botocore.exceptions import ClientError
prod_number_array_bq = []
prod_number_array_s3 = []
with open('bq-results-20191218-151637-rshujisvqrri.csv') as csv_file:
csv_reader = csv.reader(csv_file,delimiter=',')
line_count = 0
for row in csv_reader:
sliced = re.sub("[^0-9]", "", str(row))
prod_number_array_bq.append(sliced)
s3 = boto3.resource('s3')
bucket = s3.Bucket('********')
for key in bucket.objects.all():
sliced = re.sub("[^0-9]", "", str(key.key))
if((set(sliced) & set(prod_number_array_bq))!=""):
bucket.download_file(key.key,sliced + '.txt')
Help would be appreciated :)
Thanks
Upvotes: 5
Views: 10399
Reputation: 6080
In my case, I could read the file but couldn't download it
So I the following would have printed the file information
resp = s3_client.list_objects_v2(Bucket=bucket_name, Prefix=origin)
print(resp)
but then this would have given botocore.exceptions.ClientError: An error occurred (403) when calling the HeadObject operation: Forbidden
error
s3_client.download_file(bucket_name, origin, destination)
The problem was the model was uploaded from different AWS account. We were missing ACL on upload. so,
so we uploaded the file with the following command
s3_client.upload_file(origin,
bucket_name,
destination,
ExtraArgs={'ACL':'bucket-owner-full-control'})
and this led us to read and download the file as we expectd.
Upvotes: 3
Reputation: 11259
Typically when you see a 403 on HeadObject
despite having the s3:GetObject
permission, it's because the s3:ListObjects
permission wasn't provided for the bucket AND your key doesn't exist. It's a security measure to prevent exposing information about what objects are or aren't in your bucket. When you have both the s3:GetObject
permission for the objects in a bucket, and the s3:ListObjects
permission for the bucket itself, the response for a non-existent key is a 404 "no such key" response. If you only have s3:GetObject
permission and request a non-existent object, the response is a 403 "access denied".
Upvotes: 7