Description
Library name and version
Azure.Storage.DataMovement.Blobs 12.1.0
Describe the bug
Copying from a standard SKU storage account to a premium SKU storage account results in an error that the access tier is not supported.
The library insists on trying to preserve the access tier, despite the fact that access tiers are not applicable on premium SKU storage accounts.
I've looked at any way to work around this but could not find any. The library should support this scenario.
Expected behavior
I would expect this to not throw an exception. Either by autodetecting that the destination account is premium SKU (preferred), or by providing a flag on the BlobStorageResourceOptions
to disable the behavior of preserving blob access tiers (it can be enabled by default to preserve existing behavior).
Actual behavior
This exception is thrown:
Blob access tier is not supported on this storage account type.
RequestId:[Redacted]
Time:[Redacted]
Status: 400 (Blob access tier is not supported on this storage account type.)
ErrorCode: BlobAccessTierNotSupportedForAccountType
Content:
<?xml version="1.0" encoding="utf-8"?><Error><Code>BlobAccessTierNotSupportedForAccountType</Code><Message>Blob access tier is not supported on this storage account type.
RequestId:[Redacted]
Time:[Redacted]</Message></Error>
Headers:
Server: Windows-Azure-Blob/1.0 Microsoft-HTTPAPI/2.0
x-ms-request-id: [Redacted]
x-ms-client-request-id: [Redacted]
x-ms-version: 2025-01-05
x-ms-error-code: BlobAccessTierNotSupportedForAccountType
Date: [Redacted]
Content-Length: 272
Content-Type: application/xml
StackTrace
at Azure.Storage.Blobs.BlockBlobRestClient.CommitBlockListAsync(BlockLookupList blocks, Nullable`1 timeout, String blobCacheControl, String blobContentType, String blobContentEncoding, String blobContentLanguage, Byte[] blobContentMD5, Byte[] transactionalContentMD5, Byte[] transactionalContentCrc64, IDictionary`2 metadata, String leaseId, String blobContentDisposition, String encryptionKey, String encryptionKeySha256, Nullable`1 encryptionAlgorithm, String encryptionScope, Nullable`1 tier, Nullable`1 ifModifiedSince, Nullable`1 ifUnmodifiedSince, String ifMatch, String ifNoneMatch, String ifTags, String blobTagsString, Nullable`1 immutabilityPolicyExpiry, Nullable`1 immutabilityPolicyMode, Nullable`1 legalHold, CancellationToken cancellationToken)
at Azure.Storage.Blobs.Specialized.BlockBlobClient.CommitBlockListInternal(IEnumerable`1 base64BlockIds, BlobHttpHeaders blobHttpHeaders, IDictionary`2 metadata, IDictionary`2 tags, BlobRequestConditions conditions, Nullable`1 accessTier, BlobImmutabilityPolicy immutabilityPolicy, Nullable`1 legalHold, Boolean async, CancellationToken cancellationToken)
at Azure.Storage.Blobs.Specialized.BlockBlobClient.CommitBlockListAsync(IEnumerable`1 base64BlockIds, CommitBlockListOptions options, CancellationToken cancellationToken)
at Azure.Storage.DataMovement.Blobs.BlockBlobStorageResource.CompleteTransferAsync(Boolean overwrite, StorageResourceCompleteTransferOptions completeTransferOptions, CancellationToken cancellationToken)
at Azure.Storage.DataMovement.ServiceToServiceJobPart.CompleteTransferAsync(StorageResourceItemProperties sourceProperties)
Reproduction Steps
var tokenCredential = new DefaultAzureCredential();
BlobsStorageResourceProvider blobs = new(tokenCredential);
// source account must be standard SKU
var source = await blobs.FromBlobAsync(new Uri(@"https://<sourceaccount>.blob.core.windows.net/<blobname>"));
// destination account must be premium SKU
var dest = await blobs.FromBlobAsync(new Uri(@"https://<destaccount>.blob.core.windows.net/<blobname>"));
var transferManager = new TransferManager(new TransferManagerOptions());
var transferOptions = new TransferOptions();
transferOptions.ItemTransferFailed += (args) => { Console.WriteLine(args.Exception); return Task.CompletedTask; };
var transferOperation = await transferManager.StartTransferAsync(source, dest, transferOptions);
await transferOperation.WaitForCompletionAsync();
Environment
No response
Activity