Skip to content

Commit ed7ad49

Browse files
SNOW-1955965: Fix expired S3 credentials update (#2258)
1 parent 017848e commit ed7ad49

File tree

4 files changed

+15
-1
lines changed

4 files changed

+15
-1
lines changed

DESCRIPTION.md

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -20,6 +20,7 @@ Source code is also available at: https://github.com/snowflakedb/snowflake-conne
2020
- Added `check_arrow_conversion_error_on_every_column` connection property that can be set to `False` to restore previous behaviour in which driver will ignore errors until it occurs in the last column. This flag's purpose is to unblock workflows that may be impacted by the bugfix and will be removed in later releases.
2121
- Lower log levels from info to debug for some of the messages to make the output easier to follow.
2222
- Allow the connector to inherit a UUID4 generated upstream, provided in statement parameters (field: `requestId`), rather than automatically generate a UUID4 to use for the HTTP Request ID.
23+
- Fix expired S3 credentials update and increment retry when expired credentials are found.
2324

2425
- v3.14.0(March 03, 2025)
2526
- Bumped pyOpenSSL dependency upper boundary from <25.0.0 to <26.0.0.

src/snowflake/connector/file_transfer_agent.py

Lines changed: 4 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -315,6 +315,9 @@ def __init__(
315315
def update(self, cur_timestamp) -> None:
316316
with self.lock:
317317
if cur_timestamp < self.timestamp:
318+
logger.debug(
319+
"Omitting renewal of storage token, as it already happened."
320+
)
318321
return
319322
logger.debug("Renewing expired storage token.")
320323
ret = self.connection.cursor()._execute_helper(self._command)
@@ -536,7 +539,7 @@ def transfer_done_cb(
536539
) -> None:
537540
# Note: chunk_id is 0 based while num_of_chunks is count
538541
logger.debug(
539-
f"Chunk {chunk_id}/{done_client.num_of_chunks} of file {done_client.meta.name} reached callback"
542+
f"Chunk(id: {chunk_id}) {chunk_id+1}/{done_client.num_of_chunks} of file {done_client.meta.name} reached callback"
540543
)
541544
with cv_chunk_process:
542545
transfer_metadata.chunks_in_queue -= 1

src/snowflake/connector/s3_storage_client.py

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -329,6 +329,9 @@ def generate_authenticated_url_and_args_v4() -> tuple[bytes, dict[str, bytes]]:
329329
amzdate = t.strftime("%Y%m%dT%H%M%SZ")
330330
short_amzdate = amzdate[:8]
331331
x_amz_headers["x-amz-date"] = amzdate
332+
x_amz_headers["x-amz-security-token"] = self.credentials.creds.get(
333+
"AWS_TOKEN", ""
334+
)
332335

333336
(
334337
canonical_request,

src/snowflake/connector/storage_client.py

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -282,6 +282,7 @@ def _send_request_with_retry(
282282
conn = self.meta.sfagent._cursor.connection
283283

284284
while self.retry_count[retry_id] < self.max_retry:
285+
logger.debug(f"retry #{self.retry_count[retry_id]}")
285286
cur_timestamp = self.credentials.timestamp
286287
url, rest_kwargs = get_request_args()
287288
rest_kwargs["timeout"] = (REQUEST_CONNECTION_TIMEOUT, REQUEST_READ_TIMEOUT)
@@ -295,10 +296,14 @@ def _send_request_with_retry(
295296
response = rest_call(url, **rest_kwargs)
296297

297298
if self._has_expired_presigned_url(response):
299+
logger.debug(
300+
"presigned url expired. trying to update presigned url."
301+
)
298302
self._update_presigned_url()
299303
else:
300304
self.last_err_is_presigned_url = False
301305
if response.status_code in self.TRANSIENT_HTTP_ERR:
306+
logger.debug(f"transient error: {response.status_code}")
302307
time.sleep(
303308
min(
304309
# TODO should SLEEP_UNIT come from the parent
@@ -309,7 +314,9 @@ def _send_request_with_retry(
309314
)
310315
self.retry_count[retry_id] += 1
311316
elif self._has_expired_token(response):
317+
logger.debug("token is expired. trying to update token")
312318
self.credentials.update(cur_timestamp)
319+
self.retry_count[retry_id] += 1
313320
else:
314321
return response
315322
except self.TRANSIENT_ERRORS as e:

0 commit comments

Comments
 (0)