Skip to content

HeadObject error when trying to upload file to S3 #18111

@shlomi-viz

Description

@shlomi-viz

Apache Airflow Provider(s)

amazon

Versions of Apache Airflow Providers

apache-airflow-providers-ftp==2.0.1
apache-airflow-providers-http==1.1.1
apache-airflow-providers-imap==2.0.1
apache-airflow-providers-postgres==1.0.1
apache-airflow-providers-sftp==1.1.1
apache-airflow-providers-sqlite==2.0.1
apache-airflow-providers-ssh==1.3.0

Apache Airflow version

2.0.2

Operating System

Mac and Linux

Deployment

MWAA

Deployment details

No response

What happened

When trying to upload a file to another AWS account using the load_file function, I got the following

An error occurred (403) when calling the HeadObject operation: Forbidden

looking at source code the error is from

    @provide_bucket_name
    @unify_bucket_name_and_key
    def check_for_key(self, key: str, bucket_name: Optional[str] = None) -> bool:
        """
        Checks if a key exists in a bucket

        :param key: S3 key that will point to the file
        :type key: str
        :param bucket_name: Name of the bucket in which the file is stored
        :type bucket_name: str
        :return: True if the key exists and False if not.
        :rtype: bool
        """
        try:
            self.get_conn().head_object(Bucket=bucket_name, Key=key)
            return True
        except ClientError as e:
            if e.response["ResponseMetadata"]["HTTPStatusCode"] == 404:
                return False
            else:
                raise e

As I understand it I'm getting this error since I don't a List permissions on the bucket in the other account

What you expected to happen

AirFlow should try and upload the file, even if it already exists. In this section of the code we can add another check for the response code we get when no List permissions

        except ClientError as e:
            if e.response["ResponseMetadata"]["HTTPStatusCode"] == 404:
                return False
            else:
                raise e

How to reproduce

Use the following command to upload the file to an S3 bucket that you only have Get and Put permissions.

s3_hook.load_file(local_file_path, bucket_name=bucket_name, key=s3_key, acl_policy='bucket-owner-full-control')

Anything else

No response

Are you willing to submit PR?

  • Yes I am willing to submit a PR!

Code of Conduct

Metadata

Metadata

Assignees

No one assigned

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions