generate_container_sas() with user delegated key produces unusable SAS token
See original GitHub issue- Package Name: azure-storage-blob - 12.8.0 azure-identity - 1.5.0
- Operating System: Windows 10 Pro
- Python Version: 3.7.4
Describe the bug Generating a container SAS token (generate_container_sas()) using a User Delegated Key (get_user_delegation_key()) returns a SAS key, that when used to attempt to copy a blob using start_copy_from_url() returns the following error:
" azure.core.exceptions.HttpResponseError: Operation returned an invalid status ‘Server failed to authenticate the request. Make sure the value of Authorization header is formed correctly including the signature.’ … azure.core.exceptions.ResourceNotFoundError: Server failed to authenticate the request. Make sure the value of Authorization header is formed correctly including the signature. RequestId:b6897450-e01e-002e-1145-22b666000000 Time:2021-03-26T13:40:05.2439532Z ErrorCode:CannotVerifyCopySource Error:None "
Note that no error occurs when a UDK generated SAS token acquired from the portal site is used.
Below is an example of the two SAS tokens to compare formatting (any preceding ‘?’ may have been added if it wasn’t already there):
python generated: ‘?se=2021-03-26T21%3A49%3A05Z&sig=[REDACTED]&ske=2021-03-26T21%3A49%3A01Z&skoid=[REDACTED]&sks=b&skt=2021-03-26T12%3A49%3A01Z&sktid=[REDACTED]&skv=2020-06-12&sp=racwl&spr=https&sr=c&st=2021-03-26T12%3A49%3A05Z&sv=2020-06-12’
portal generated: ‘?se=2021-03-25T16:19:40Z&sig=[REDACTED]&ske=2021-03-25T16:19:40Z&skoid=[REDACTED]&sks=b&skt=2021-03-25T08:19:40Z&sktid=[REDACTED]&skv=2020-02-10&sp=racwl&spr=https&sr=c&st=2021-03-25T08:19:40Z&sv=2020-02-10’
To Reproduce Steps to reproduce the behavior:
from azure.storage.blob import BlobServiceClient, generate_container_sas
from azure.identity import DefaultAzureCredential
from datetime import datetime, timedelta
account_name = [Source blob account URL]
target_account_name = [target account URL]
container_name = [some container name]
target_container_name = [some container name]
target_file_path = [some blob URL]
source_blob = [some blob_URL]
default_credential = DefaultAzureCredential(exclude_interactive_browser_credential=False, exclude_shared_token_cache_credential=True, exclude_visual_studio_code_credential=True, exclude_managed_identity_credential=True, exclude_environment_credential=True, exclude_cli_credential=True)
blob_service = BlobServiceClient(target_account_name, credential=default_credential)
blob_service_source = BlobServiceClient(account_name, credential=default_credential)
udk = blob_service_source.get_user_delegation_key(datetime.utcnow()-timedelta(hours=1), datetime.utcnow()+ timedelta(hours=8))
sas_token = generate_container_sas(account_name,user_delegation_key=udk,container_name=container_name,
permission='racwl', start=datetime.utcnow()-timedelta(hours=1), expiry=datetime.utcnow()+ timedelta(hours=8), protocol='https')
if sas_token[0]!='?':
sas_token = '?'+sas_token
copied_blob = blob_service.get_blob_client(target_container_name, target_file_path)
copied_blob.start_copy_from_url(source_blob + sas_token)
Expected behavior It is expected that the generated SAS token would be accepted similar to if one was generated for a container using UDK in the portal.
Additional context The storage accounts in question are private but the user has Storage Blob Data Contributor role assignment. I noted that a difference between the SAS tokens was the URL encoding in the python generated SAS but that happens with the generate_container_sas() function and I can’t seem to amend that. I tried using a string time format that wasn’t URL encoded but got the same response
Issue Analytics
- State:
- Created 2 years ago
- Comments:6 (2 by maintainers)

Top Related StackOverflow Question
Hi @James-Beckwith
Sorry for the delay. It looks like the problem happened in this line
sas_token = generate_container_sas(account_name,user_delegation_key=udk,container_name=container_name,theaccount_nameshould be the account name instead of account url which is named as account_nameaccount_name = [Source blob account URL]Let me know if that doesn’t work!
@xiafu-msft - indeed this worked. Thank you for the help.