abpframework/abp · error · BlobAlreadyExistsException

Saving BLOB '{args.BlobName}' does already exists in the con

Error message

Saving BLOB '{args.BlobName}' does already exists in the container '{GetContainerName(args)}'! Set OverrideExisting if it should be overwritten.

What it means

Thrown by AzureBlobProvider.SaveAsync when OverrideExisting is false and AzureBlobNameCalculator-calculated blob name already exists in the container, as determined by BlobExistsAsync. It prevents silent overwrites of existing Azure blobs; the check runs before CreateContainerIfNotExists and the actual UploadAsync call.

Source

Thrown at framework/src/Volo.Abp.BlobStoring.Azure/Volo/Abp/BlobStoring/Azure/AzureBlobProvider.cs:29

    protected IAzureBlobNameCalculator AzureBlobNameCalculator { get; }
    protected IBlobNormalizeNamingService BlobNormalizeNamingService { get; }

    public AzureBlobProvider(
        IAzureBlobNameCalculator azureBlobNameCalculator,
        IBlobNormalizeNamingService blobNormalizeNamingService)
    {
        AzureBlobNameCalculator = azureBlobNameCalculator;
        BlobNormalizeNamingService = blobNormalizeNamingService;
    }

    public override async Task SaveAsync(BlobProviderSaveArgs args)
    {
        var blobName = AzureBlobNameCalculator.Calculate(args);
        var configuration = args.Configuration.GetAzureConfiguration();

        if (!args.OverrideExisting && await BlobExistsAsync(args, blobName))
        {
            throw new BlobAlreadyExistsException($"Saving BLOB '{args.BlobName}' does already exists in the container '{GetContainerName(args)}'! Set {nameof(args.OverrideExisting)} if it should be overwritten.");
        }

        if (configuration.CreateContainerIfNotExists)
        {
            await CreateContainerIfNotExists(args);
        }

        await GetBlobClient(args, blobName).UploadAsync(args.BlobStream, true);
    }

    public override async Task<bool> DeleteAsync(BlobProviderDeleteArgs args)
    {
        var blobName = AzureBlobNameCalculator.Calculate(args);

        if (await BlobExistsAsync(args, blobName))
        {
            return await GetBlobClient(args, blobName).DeleteIfExistsAsync();
        }

View on GitHub (pinned to 7ed43b1931)

Solutions

  1. Pass overrideExisting: true when the new content should replace the existing blob.
  2. Use a unique blob name per save to avoid collisions entirely.
  3. Call ExistsAsync first and branch your logic.
  4. Delete the stale blob before re-saving under the same key.

Example fix

// before
await container.SaveAsync("report.pdf", stream);

// after
await container.SaveAsync("report.pdf", stream, overrideExisting: true);
Defensive patterns

Strategy: validation

Validate before calling

if (await container.ExistsAsync(blobName))
{
    await container.SaveAsync(blobName, stream, overrideExisting: true);
    return;
}
await container.SaveAsync(blobName, stream);

Type guard

bool willConflict = !args.OverrideExisting && await container.ExistsAsync(blobName);

Try / catch

try { await container.SaveAsync(blobName, stream); }
catch (BlobAlreadyExistsException)
{ /* rename key or retry with overrideExisting: true */ }

Prevention

When it happens

Trigger: Saving a blob through the Azure provider where the target blob name already exists and OverrideExisting was not set to true. Note that even with this guard, the subsequent UploadAsync passes overwrite:true to the BlobClient, so this exception is the only overwrite barrier.

Common situations: Re-saving a stable-key blob (user avatar, generated report), retrying an upload that completed server-side, or concurrent writers racing for the same key.

Related errors


AI-assisted analysis of abpframework/abp@7ed43b1931 (2026-08-13). Data as JSON: /api/errors/e08e15e0e24324dc. Report an issue: GitHub.