Azure-sdk-for-net: [BUG] Error when reading an empty blob with BlobClient.DownloadToAsync

Created on 6 May 2020  ·  3Comments  ·  Source: Azure/azure-sdk-for-net

Bug description
When an empty (0-byte) blob is being read with BlobClient.DownloadToAsync(Stream..), an exception is thrown:

Azure.RequestFailedException: The range specified is invalid for the current size of the resource
Status: 416 (The range specified is invalid for the current size of the resource.)
ErrorCode: InvalidRange

The issue seems similar with #https://github.com/Azure/azure-sdk-for-net/issues/10827 which seems to be fixed, however the problem still appears.

Expected behavior
The call should not crash and an empty stream should be returned.

Actual behavior
Azure.RequestFailedException is thrown:

Unhandled Exception: Azure.RequestFailedException: The range specified is invalid for the current size of the resource.
RequestId:3462f82e-001e-004e-2ea5-232c62000000
Time:2020-05-06T12:57:52.6984058Z
Status: 416 (The range specified is invalid for the current size of the resource.)
ErrorCode: InvalidRange

Headers:
x-ms-request-id: ...
x-ms-client-request-id: ...
x-ms-version: 2019-07-07
x-ms-error-code: InvalidRange
Date: Wed, 06 May 2020 12:57:52 GMT
Server: Windows-Azure-Blob/1.0,Microsoft-HTTPAPI/2.0
Content-Length: 249
Content-Range: bytes */0
Content-Type: application/xml
   at Azure.Storage.Blobs.BlobRestClient.Blob.DownloadAsync_CreateResponse(ClientDiagnostics clientDiagnostics, Response response)
   at Azure.Storage.Blobs.BlobRestClient.Blob.<DownloadAsync>d__0.MoveNext()
   at System.Threading.Tasks.ValueTask`1.get_Result()
   at Azure.Storage.Blobs.Specialized.BlobBaseClient.<StartDownloadAsync>d__45.MoveNext()
   at Azure.Storage.Blobs.Specialized.BlobBaseClient.<DownloadInternal>d__44.MoveNext()
   at Azure.Storage.Blobs.Specialized.BlobBaseClient.<DownloadAsync>d__43.MoveNext()
   at Azure.Storage.Blobs.PartitionedDownloader.<DownloadToAsync>d__5.MoveNext()
   at Azure.Storage.Blobs.Specialized.BlobBaseClient.<StagedDownloadAsync>d__58.MoveNext()
   at Azure.Storage.Blobs.Specialized.BlobBaseClient.<DownloadToAsync>d__56.MoveNext()
   at Azure.Storage.Blobs.Specialized.BlobBaseClient.<DownloadToAsync>d__52.MoveNext()
   at Azure.Storage.Blobs.Specialized.BlobBaseClient.<DownloadToAsync>d__48.MoveNext()

To Reproduce
Call
var memoryStream = new MemoryStream();
await blobClient.DownloadToAsync(memoryStream);
on an 0-byte blob:

using System.IO;
using System.Text;
using System.Threading.Tasks;
using Azure.Storage.Blobs;

namespace BlobClientDownloadToAsyncErrorEmptyBlob
{
    internal static class Program
    {
        static async Task Main()
        {
            const string storageAccountConnStr = "DefaultEndpointsProtocol=https;AccountName=....;AccountKey=...;EndpointSuffix=core.windows.net";

            // create the container
            BlobServiceClient blobServiceClient = new BlobServiceClient(storageAccountConnStr);
            BlobContainerClient containerClient = blobServiceClient.GetBlobContainerClient("testcontainer");
            await containerClient.CreateIfNotExistsAsync();

            // write the blob
            const string blobContent = ""; // empty string
            BlobClient blobClient = containerClient.GetBlobClient("testblob");
            await blobClient.UploadAsync(new MemoryStream(Encoding.UTF8.GetBytes(blobContent)), overwrite: true);

            // read the 0-bytes blob
            var memoryStream = new MemoryStream();
            // throws  Azure.RequestFailedException: The range specified is invalid for the current size of the resource.
            // Status: 416 (The range specified is invalid for the current size of the resource.)
            // ErrorCode: InvalidRange
            await blobClient.DownloadToAsync(memoryStream);

            // ...
        }
    }
}

Environment:

  • Azure.Storage.Blobs 12.4.1 package; Azure.Core 1.2.0; Azure.Storage.Common 12.4.0
  • Windows 10 .NET Framework 4.7.2 or 4.6.2 (running in a console app or in an Azure App Service)
  • Visual Studio 2019

    • Azure StorageV2 account; Access tier: Standard/Hot

      image

Client Service Attention Storage customer-reported question

All 3 comments

Thanks for the feedback! We are routing this to the appropriate team for follow-up. cc @xgithubtriage.

Hi,

I was able to reproduce your issue.

Looks like the only way to work around this is to call the regular Download method and use the copyTo Stream

BlobDownloadInfo download = blob.Download();
using (MemoryStream stream = new MemoryStream())
{
     download.Content.CopyTo(stream);
}

--

Looks like we give it a range when attempting to staged download. The service does not seem to like this that much because it throws a 416, when providing a range on trying to download an empty blob. I will update this issue once more investigation has been done.

Was this page helpful?
0 / 5 - 0 ratings