-
Notifications
You must be signed in to change notification settings - Fork 3.3k
Description
This issue started happening on or around 5/5/2025. Prior to that this was working fine. The issue was originally reported over in the azure-storage-azcopy repo (see Issue #3039). Cross-posting the issue since the exact same behavior is being exhibited in the upload_blob_from_url function in azure.storage.blob.BlobClient.
See details below, including the error returned from the upload_blob_from_url call...
Also, having the same issue and it started failing on or around 5/5/2025.
What we've observed so far...
Using an AWS S3 presigned URL as the source URL, both AzCopy and Azure SDK for Python produce the
CannotVerifyCopySourceerror code with a403 Forbiddenstatus code as the error message.Using
azcopy copyproduces:azcopy copy "https://[bucket].s3.amazonaws.com/foo/bar/baz.jpg?AWSAccessKeyId=[...]&Signature=[...]&x-amz-security-token=[...]&Expires=[...]" "https://mystorageaccount.blob.core.windows.net/foo/bar/baz.jpg" --from-to BlobBlob --overwrite true INFO: Scanning... INFO: Failed to create one or more destination container(s). Your transfers may still succeed if the container already exists. INFO: Any empty folders will not be processed, because source and/or destination doesn't have full folder support failed to perform copy command due to error: cannot start job due to error: cannot list files due to reason HEAD https://[bucket].s3.amazonaws.com/foo/bar/baz.jpg -------------------------------------------------------------------------------- RESPONSE 403: 403 Forbidden ERROR CODE UNAVAILABLE -------------------------------------------------------------------------------- Response contained no body -------------------------------------------------------------------------------- .Using Azure SDK for Python > azure.storage.blob.BlobClient > upload_blob_from_url produces:
Forbidden RequestId:[...] Time:2025-05-07T19:26:39.9776804Z ErrorCode:CannotVerifyCopySource copysourcestatuscode:403 copysourceerrormessage:Forbidden Content: <?xml version="1.0" encoding="utf-8"?> <Error> <Code>CannotVerifyCopySource</Code> <Message>Forbidden RequestId:[...] Time:2025-05-07T19:26:39.9776804Z </Message> <CopySourceStatusCode>403</CopySourceStatusCode> <CopySourceErrorMessage>Forbidden</CopySourceErrorMessage> </Error>We verified everything is working as expected in AWS...
- the presigned URL is valid
- token is not expired
- bucket has all the correct policies applied, etc.
So where is the
403 Forbiddencoming from?Before the copy begins, Azure is performing an initial
HEADrequest on the Source URL (presumably to verify the copy source URL is valid). The error in Azure is originating during this HEAD request.There’s 2 potential reasons these calls began failing on or around 5/5/2025:
- Azure is no longer including the query string parameters in the HEAD request. For presigned URLs, the query string parameters contain the authorization token, so not including the query string parameters causes a
403 Forbiddenerror.- Azure is including the query string parameter, however AWS presigned URLs which were signed for the action
get_objectdon’t allow both GET and HEAD requests.To eliminate #2 as an option, we used a CloudFront distribution to ensure that we could serve up a pre-signed URL that allows both GET and HEAD requests. Using the CloudFront presigned URL as the Source URL also resulted in a
403 Forbidden. Therefore, we do not believe that reason #2 is the problem.Performing an
azcopy copyusing a CloudFront presigned URL:azcopy copy "https://[REDACTED].cloudfront.net/foo/bar/baz.jpg?Policy=[REDACTED]&Signature=[REDACTED]&Key-Pair-Id=[REDACTED]" "https://[REDACTED].blob.core.windows.net/foo/bar/baz.jpg?sv=[...]&se=2025-05-08T01%3A25%3A45Z&sr=b&sp=rcw&sig=[REDACTED]&rscc=max-age%3D0" --from-to BlobBlob --overwrite true INFO: Scanning... INFO: Failed to create one or more destination container(s). Your transfers may still succeed if the container already exists. INFO: Any empty folders will not be processed, because source and/or destination doesn't have full folder support failed to perform copy command due to error: cannot start job due to error: cannot list files due to reason HEAD https://[REDACTED].cloudfront.net/foo/bar/baz.jpg -------------------------------------------------------------------------------- RESPONSE 403: 403 Forbidden ERROR CODE UNAVAILABLE -------------------------------------------------------------------------------- Response contained no body -------------------------------------------------------------------------------- .In the error message above, you can see that the
HEADrequest URL omits the query string parameters.Performing the HEAD request with the full URL produces a
200 OKresponse:curl --head "https://[REDACTED].cloudfront.net/foo/bar/baz.jpg?Policy=[REDACTED]&Signature=[REDACTED]&Key-Pair-Id=[REDACTED]" HTTP/2 200 [...]Performing the HEAD request without query string params produces a
403 Forbiddenresponse:curl --head "https://[REDACTED].cloudfront.net/foo/bar/baz.jpg" HTTP/1.1 403 Forbidden [...]Conclusion
Beginning on or around 5/5/2025, we believe the verification logic Azure uses on Source URLs changed — at least for AWS S3 presigned URLs. Azure is no longer including query string parameters in an initial HEAD request it performs on the Source URL. This causes the HEAD request to fail with a 403 Forbidden status code, resulting in a
CannotVerifyCopySourceerror.
Originally posted by @jacobbgarland in #3039