Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

boto3.client.get_object is prepending the bucket name to the file key #3654

Closed
antoinebrtd opened this issue Apr 5, 2023 · 6 comments
Closed
Assignees
Labels
bug This issue is a confirmed bug. p2 This is a standard priority issue response-requested Waiting on additional information or feedback. s3

Comments

@antoinebrtd
Copy link

antoinebrtd commented Apr 5, 2023

Describe the bug

I recently updated boto3 to the latest version and I am trying to access a file using boto3.client.get_object from my backend.

I uploaded a file from S3 console at the "root" of the bucket, so I am sure myfile.png exists with the specified key. When I try to download it using the code below, it looks like it is incorrectly prepending the bucket name to the file path, so it can't find the file. I keep getting 404 errors:

ClientError: An error occurred (NoSuchKey) when calling the GetObject operation: The specified key does not exist.

Expected Behavior

I would expect the object to be found correctly. It was working before updating boto3.

Current Behavior

I have to move myfile.png from the root of the bucket to a folder with the same name as the bucket for boto3 to find the file. So this:

obj = storage.get_object(Bucket="my-bucket", Key="myfile.png")['Body']

is actually resolving the path to my-bucket/myfile.png inside my-bucket bucket

Reproduction Steps

Create a bucket in eu-west-3 region from s3 console and an access point alias to that bucket, and upload a file at the root of the bucket. Create access keys in iam with read access. Run the following code. From s3 console create a folder in the bucket with the same name as the bucket and move the file in it, run the code again

import boto3

storage = boto3.client(
    "s3",
    aws_access_key_id="ACCESS_KEY",
    aws_secret_access_key="SECRET_KEY",
    endpoint_url="https://my-bucket-access-point-alias.s3.eu-west-3.amazonaws.com/"
)

obj = storage.get_object(Bucket="my-bucket", Key="myfile.png")['Body']

Possible Solution

No response

Additional Information/Context

No response

SDK version used

1.26.94

Environment details (OS name and version, etc.)

Linux server

@antoinebrtd antoinebrtd added bug This issue is a confirmed bug. needs-triage This issue or PR still needs to be triaged. labels Apr 5, 2023
@antoinebrtd antoinebrtd changed the title boto3.client.get_object is prepending the bucket name to the key boto3.client.get_object is prepending the bucket name to the file key Apr 5, 2023
@RyanFitzSimmonsAK RyanFitzSimmonsAK self-assigned this Apr 5, 2023
@RyanFitzSimmonsAK RyanFitzSimmonsAK added s3 investigating This issue is being investigated and/or work is in progress to resolve the issue. and removed needs-triage This issue or PR still needs to be triaged. labels Apr 5, 2023
@antoinebrtd
Copy link
Author

The same issue occurs with upload_fileobj and delete_object

@RyanFitzSimmonsAK
Copy link
Contributor

Hi @antoinebrtd, thanks for reaching out. Could you provide debug logs of a run where this behavior occurs? You can get debug logs by adding boto3.set_stream_logger('') to the top of your script, and redacting any sensitive information. Thanks!

@antoinebrtd
Copy link
Author

antoinebrtd commented Apr 6, 2023

@RyanFitzSimmonsAK

2023-04-06 09:40:24,267 botocore.hooks [DEBUG] Event choose-service-name: calling handler <function handle_service_name_alias at 0x10672be20>
2023-04-06 09:40:24,267 botocore.hooks [DEBUG] Event creating-client-class.s3: calling handler <function add_generate_presigned_post at 0x10667e340>
2023-04-06 09:40:24,267 botocore.hooks [DEBUG] Event creating-client-class.s3: calling handler <function lazy_call.<locals>._handler at 0x1061393a0>
2023-04-06 09:40:24,268 botocore.hooks [DEBUG] Event creating-client-class.s3: calling handler <function add_generate_presigned_url at 0x10667e0c0>
2023-04-06 09:40:24,269 botocore.endpoint [DEBUG] Setting s3 timeout as (60, 60)
2023-04-06 09:40:24,270 botocore.client [DEBUG] Registering retry handlers for service: s3
2023-04-06 09:40:24,270 botocore.utils [DEBUG] Registering S3 region redirector handler
2023-04-06 09:40:24,271 botocore.hooks [DEBUG] Event before-endpoint-resolution.s3: calling handler <function customize_endpoint_resolver_builtins at 0x10674fb00>
2023-04-06 09:40:24,271 botocore.hooks [DEBUG] Event before-endpoint-resolution.s3: calling handler <bound method S3RegionRedirectorv2.redirect_from_cache of <botocore.utils.S3RegionRedirectorv2 object at 0x1079e3190>>
2023-04-06 09:40:24,271 botocore.regions [DEBUG] Calling endpoint provider with parameters: {'Bucket': 'my-bucket', 'Region': 'eu-west-3', 'UseFIPS': False, 'UseDualStack': False, 'Endpoint': 'https://my-bucket-access-point-alias.s3.eu-west-3.amazonaws.com/', 'ForcePathStyle': True, 'Accelerate': False, 'UseGlobalEndpoint': False, 'DisableMultiRegionAccessPoints': False, 'UseArnRegion': True}
2023-04-06 09:40:24,271 botocore.regions [DEBUG] Endpoint provider result: https://my-bucket-access-point-alias..s3.eu-west-3.amazonaws.com/my-bucket
2023-04-06 09:40:24,271 botocore.regions [DEBUG] Selecting from endpoint provider's list of auth schemes: "sigv4". User selected auth scheme is: "None"
2023-04-06 09:40:24,271 botocore.regions [DEBUG] Selected auth type "v4" as "v4" with signing context params: {'region': 'eu-west-3', 'signing_name': 's3', 'disableDoubleEncoding': True}
2023-04-06 09:40:24,271 botocore.hooks [DEBUG] Event before-parameter-build.s3.GetObject: calling handler <function sse_md5 at 0x10674d8a0>
2023-04-06 09:40:24,271 botocore.hooks [DEBUG] Event before-parameter-build.s3.GetObject: calling handler <function validate_bucket_name at 0x10674d800>
2023-04-06 09:40:24,271 botocore.hooks [DEBUG] Event before-parameter-build.s3.GetObject: calling handler <function remove_bucket_from_url_paths_from_model at 0x10674f920>
2023-04-06 09:40:24,271 botocore.hooks [DEBUG] Event before-parameter-build.s3.GetObject: calling handler <bound method S3RegionRedirectorv2.annotate_request_context of <botocore.utils.S3RegionRedirectorv2 object at 0x1079e3190>>
2023-04-06 09:40:24,271 botocore.hooks [DEBUG] Event before-parameter-build.s3.GetObject: calling handler <function generate_idempotent_uuid at 0x10674d620>
2023-04-06 09:40:24,271 botocore.hooks [DEBUG] Event before-call.s3.GetObject: calling handler <function add_expect_header at 0x10674dbc0>
2023-04-06 09:40:24,271 botocore.hooks [DEBUG] Event before-call.s3.GetObject: calling handler <function add_recursion_detection_header at 0x10672bec0>
2023-04-06 09:40:24,271 botocore.hooks [DEBUG] Event before-call.s3.GetObject: calling handler <function inject_api_version_header_if_needed at 0x10674f100>
2023-04-06 09:40:24,271 botocore.endpoint [DEBUG] Making request for OperationModel(name=GetObject) with params: {'url_path': 'myfile.png', 'query_string': {}, 'method': 'GET', 'headers': {'User-Agent': 'Boto3/1.26.94 Python/3.11.2 Darwin/22.4.0 Botocore/1.29.94'}, 'body': b'', 'auth_path': '/my-bucket/my-file.png', 'url': 'https://my-bucket-access-point-alias.s3.eu-west-3.amazonaws.com/my-bucket/my-file.png', 'context': {'client_region': 'eu-west-3', 'client_config': <botocore.config.Config object at 0x1079e21d0>, 'has_streaming_input': False, 'auth_type': 'v4', 'signing': {'region': 'eu-west-3', 'signing_name': 's3', 'disableDoubleEncoding': True}, 's3_redirect': {'redirected': False, 'bucket': 'my-bucket', 'params': {'Bucket': 'my-bucket', 'Key': 'myfile.png'}}}}
2023-04-06 09:40:24,272 botocore.hooks [DEBUG] Event request-created.s3.GetObject: calling handler <bound method RequestSigner.handler of <botocore.signers.RequestSigner object at 0x1079d07d0>>
2023-04-06 09:40:24,272 botocore.hooks [DEBUG] Event choose-signer.s3.GetObject: calling handler <function set_operation_specific_signer at 0x10674d4e0>
2023-04-06 09:40:24,272 botocore.hooks [DEBUG] Event before-sign.s3.GetObject: calling handler <function remove_arn_from_signing_path at 0x10674fa60>
2023-04-06 09:40:24,272 botocore.auth [DEBUG] Calculating signature using v4 auth.
2023-04-06 09:40:24,272 botocore.auth [DEBUG] CanonicalRequest:
GET
/my-bucket/myfile.png
host:my-bucket-access-point-alias.s3.eu-west-3.amazonaws.com
x-amz-content-sha256:e3b0c44298fc1c149afbf4c8996fb92427ae41e4649b934ca495991b7852b855
x-amz-date:20230406T134024Z
host;x-amz-content-sha256;x-amz-date
e3b0c44298fc1c149afbf4c8996fb92427ae41e4649b934ca495991b7852b855
2023-04-06 09:40:24,272 botocore.auth [DEBUG] StringToSign:
AWS4-HMAC-SHA256
20230406T134024Z
20230406/eu-west-3/s3/aws4_request
a355280573b2fa9bb85b5132471082f58cfb04db374849e9128f89d8d83584ac
2023-04-06 09:40:24,272 botocore.auth [DEBUG] Signature:
614930227351453d13c749c35105a895bf923f3489u3dn39dnq85f596667
2023-04-06 09:40:24,272 botocore.hooks [DEBUG] Event request-created.s3.GetObject: calling handler <function add_retry_headers at 0x10674f880>
2023-04-06 09:40:24,272 botocore.endpoint [DEBUG] Sending http request: <AWSPreparedRequest stream_output=True, method=GET, url=https://my-bucket-access-point-alias.s3.eu-west-3.amazonaws.com/my-bucket/myfile.png, headers={'User-Agent': b'Boto3/1.26.94 Python/3.11.2 Darwin/22.4.0 Botocore/1.29.94', 'X-Amz-Date': b'20230406T134024Z', 'X-Amz-Content-SHA256': b'e3b0c44298fc1c149afbf4c8996fb92427ae41e4649b934ca495991b7852b855', 'Authorization': b'AWS4-HMAC-SHA256 Credential=ACCESS_KEY/20230406/eu-west-3/s3/aws4_request, SignedHeaders=host;x-amz-content-sha256;x-amz-date, Signature=614930227351453d13c749c35105a895bf923f3489u3dn39dnq85f596667', 'amz-sdk-invocation-id': b'ab9627d5-5034-43fc-916c-4ef95ea4b525', 'amz-sdk-request': b'attempt=1'}>
2023-04-06 09:40:24,272 botocore.httpsession [DEBUG] Certificate path: /home/venv/lib/python3.11/site-packages/certifi/cacert.pem
2023-04-06 09:40:24,272 urllib3.connectionpool [DEBUG] Starting new HTTPS connection (1): my-bucket-access-point-alias.s3.eu-west-3.amazonaws.com:443
2023-04-06 09:40:24,821 urllib3.connectionpool [DEBUG] https://my-bucket-access-point-alias.s3.eu-west-3.amazonaws.com:443 "GET /my-bucket/myfile.png HTTP/1.1" 404 None
2023-04-06 09:40:24,828 botocore.parsers [DEBUG] Response headers: {'x-amz-request-id': 'NCM7BHFCS0Z6R5VD', 'x-amz-id-2': '/b58Fq/55z6M46ZoVRdfvVj5Xnm1RmNYztKtoLvU3s6ZZvw74RpNz7J3OlKfWK6q2CmAB66h5nQ=', 'Content-Type': 'application/xml', 'Transfer-Encoding': 'chunked', 'Date': 'Thu, 06 Apr 2023 13:40:24 GMT', 'Server': 'AmazonS3'}
2023-04-06 09:40:24,829 botocore.parsers [DEBUG] Response body:
b'<?xml version="1.0" encoding="UTF-8"?>\n<Error><Code>NoSuchKey</Code><Message>The specified key does not exist.</Message><Key>my-bucket/myfile.png</Key><RequestId>NCM7BHFCS0Z6R5VD</RequestId><HostId>/b58Fq/55z6M46ZoVRdfvVj5Xnm1RmNYztKtoLvU3s6ZZvw74RpNz7J3OlKfWK6q2CmAB66h5nQ=</HostId></Error>'
2023-04-06 09:40:24,832 botocore.parsers [DEBUG] Response headers: {'x-amz-request-id': 'NCM7BHFCS0Z6R5VD', 'x-amz-id-2': '/b58Fq/55z6M46ZoVRdfvVj5Xnm1RmNYztKtoLvU3s6ZZvw74RpNz7J3OlKfWK6q2CmAB66h5nQ=', 'Content-Type': 'application/xml', 'Transfer-Encoding': 'chunked', 'Date': 'Thu, 06 Apr 2023 13:40:24 GMT', 'Server': 'AmazonS3'}
2023-04-06 09:40:24,832 botocore.parsers [DEBUG] Response body:
b'<?xml version="1.0" encoding="UTF-8"?>\n<Error><Code>NoSuchKey</Code><Message>The specified key does not exist.</Message><Key>my-bucket/myfile.png</Key><RequestId>NCM7BHFCS0Z6R5VD</RequestId><HostId>/b58Fq/55z6M46ZoVRdfvVj5Xnm1RmNYztKtoLvU3s6ZZvw74RpNz7J3OlKfWK6q2CmAB66h5nQ=</HostId></Error>'
2023-04-06 09:40:24,832 botocore.hooks [DEBUG] Event needs-retry.s3.GetObject: calling handler <botocore.retryhandler.RetryHandler object at 0x1079f6cd0>
2023-04-06 09:40:24,832 botocore.retryhandler [DEBUG] No retry needed.
2023-04-06 09:40:24,832 botocore.hooks [DEBUG] Event needs-retry.s3.GetObject: calling handler <bound method S3RegionRedirectorv2.redirect_from_error of <botocore.utils.S3RegionRedirectorv2 object at 0x1079e3190>>
Traceback (most recent call last):
  File "/Applications/PyCharm.app/Contents/plugins/python/helpers/pydev/pydevconsole.py", line 364, in runcode
    coro = func()
           ^^^^^^
  File "<input>", line 12, in <module>
  File "/home/venv/lib/python3.11/site-packages/botocore/client.py", line 530, in _api_call
    return self._make_api_call(operation_name, kwargs)
           ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
  File "/home/venv/lib/python3.11/site-packages/botocore/client.py", line 962, in _make_api_call
    raise error_class(parsed_response, operation_name)
botocore.errorfactory.NoSuchKey: An error occurred (NoSuchKey) when calling the GetObject operation: The specified key does not exist.
NoSuchKey
<class 'botocore.errorfactory.NoSuchKey'>

^ Removed the access keys and signature is a fake random string

@antoinebrtd
Copy link
Author

antoinebrtd commented Apr 6, 2023

Changing the dependencies from

boto3==1.26.94
botocore==1.29.94
jmespath==1.0.1
s3transfer==0.6.0

to

boto3==1.20.23
botocore==1.23.23
jmespath==0.10.0
s3transfer==0.5.0

and removing the region_name argument fixes the issue

I would expect region_name to have no effect since the region is already specified in the access point host

@RyanFitzSimmonsAK
Copy link
Contributor

Can you go into more detail about why you are specifying an endpoint_url? If endpoint_url is left empty, Boto3 will always connect to AWS, which it looks like you are trying to do. Overriding that variable is only necessary if you are using non-AWS S3 storage.

@RyanFitzSimmonsAK RyanFitzSimmonsAK added response-requested Waiting on additional information or feedback. p2 This is a standard priority issue and removed investigating This issue is being investigated and/or work is in progress to resolve the issue. labels Apr 6, 2023
@jcheenatcode
Copy link

Can you go into more detail about why you are specifying an endpoint_url? If endpoint_url is left empty, Boto3 will always connect to AWS, which it looks like you are trying to do. Overriding that variable is only necessary if you are using non-AWS S3 storage.

For anyone having this issue, commenting out the endpoint_url has resolved my issue.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
bug This issue is a confirmed bug. p2 This is a standard priority issue response-requested Waiting on additional information or feedback. s3
Projects
None yet
Development

No branches or pull requests

3 participants