Azure / azure-sdk-for-net

This repository is for active development of the Azure SDK for .NET. For consumers of the SDK we recommend visiting our public developer docs at https://learn.microsoft.com/dotnet/azure/ or our versioned developer docs at https://azure.github.io/azure-sdk-for-net.
MIT License
5.47k stars 4.8k forks source link

[BUG] containerClient.CreateIfNotExistsAsync keep throw 409 #39845

Open axlvlv opened 11 months ago

axlvlv commented 11 months ago

Library name and version

Azure.Storage.Blobs 12.14.1

Describe the bug

I use this code to create the container if not exists.

                BlobContainerClient containerClient = _blobServiceClient.GetBlobContainerClient(containerName);

                await containerClient.CreateIfNotExistsAsync(cancellationToken: cancellationToken);

It keeps have error 409 for every request, but I just have one fixed container name.

Azure.RequestFailedException: The specified container already exists. RequestId:48e36989-001e-0070-7e15-125d9d000000 Time:2023-11-08T07:31:27.8623680Z Status: 409 (The specified container already exists.) ErrorCode: ContainerAlreadyExists

After the 409 error, the blob can still upload the content I have successfully. Just wonder if this is a bug? If the container already exists, it should not throw 409 and just upload the content.

Any thought? Thanks!

Expected behavior

No 409 error logged in my application insights, it should just continue to upload the content into blob if the container name already exists.

Actual behavior

Have 409 error logs for every requests. 409 (The specified container already exists.)

But still able to upload the content successfully after the error.

Reproduction Steps

Use this code below to upload content to blob

try { BlobContainerClient containerClient = _blobServiceClient.GetBlobContainerClient(containerName);

                **await containerClient.CreateIfNotExistsAsync(cancellationToken: cancellationToken);**

                BlobClient blobClient = containerClient.GetBlobClient(blobName);

                using (MemoryStream stream = new MemoryStream(content))
                {
                    await blobClient.UploadAsync(stream, false, cancellationToken);
                }
            }
            catch (RequestFailedException e)
            {
                throw new ApplicationException($"Failed to upload blob '{blobName}' to container '{containerName}'. Exception: {e.Message}", e);
            }

Environment

.net 6 framework

github-actions[bot] commented 11 months ago

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

pallavit commented 11 months ago

Thank you for reporting the issue. Tagging and routing to the team best able to assist you. /cc:@seanmcc-msft

luthus commented 2 months ago

@axlvlv I believe this is due to the underlying calls that CreateIfNotExistsAsync makes. It doesn't actually check if the container exists before attempting to create it, instead handling the exception when it already exists, hence the 409 response.

I do think this method doesn't work as its name implies. It doesn't check whether the container exists first. As it's calling Create every time, you'll also be charged for a "List and Create Container Operation".

I'd recommend using ExistsAsync instead as this is charged at the "All other operations" rate which is about 50x cheaper.