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 '{containerName}'! Set OverrideExisting if it should be overwritten. What it means
Thrown by AliyunBlobProvider.SaveAsync when a blob is saved without OverrideExisting=true and an object with the same (calculated) blob name already exists in the OSS bucket. It is a data-integrity guard preventing accidental silent overwrites of existing stored objects. The check first confirms the bucket exists (DoesBucketExist) and then that the object exists (DoesObjectExist) before PutObject is ever called.
Source
Thrown at framework/src/Volo.Abp.BlobStoring.Aliyun/Volo/Abp/BlobStoring/Aliyun/AliyunBlobProvider.cs:45
var aliyunConfig = blobContainerConfiguration.GetAliyunConfiguration();
return OssClientFactory.Create(aliyunConfig);
}
protected virtual IOss GetOssClient(AliyunBlobProviderConfiguration aliyunConfig)
{
return OssClientFactory.Create(aliyunConfig);
}
public override Task SaveAsync(BlobProviderSaveArgs args)
{
var containerName = GetContainerName(args);
var blobName = AliyunBlobNameCalculator.Calculate(args);
var aliyunConfig = args.Configuration.GetAliyunConfiguration();
var ossClient = GetOssClient(aliyunConfig);
if (!args.OverrideExisting && BlobExists(ossClient, containerName, blobName))
{
throw new BlobAlreadyExistsException($"Saving BLOB '{args.BlobName}' does already exists in the container '{containerName}'! Set {nameof(args.OverrideExisting)} if it should be overwritten.");
}
if (aliyunConfig.CreateContainerIfNotExists)
{
if (!ossClient.DoesBucketExist(containerName))
{
ossClient.CreateBucket(containerName);
}
}
ossClient.PutObject(containerName, blobName, args.BlobStream);
return Task.CompletedTask;
}
public override Task<bool> DeleteAsync(BlobProviderDeleteArgs args)
{
var containerName = GetContainerName(args);
var blobName = AliyunBlobNameCalculator.Calculate(args);
var ossClient = GetOssClient(args.Configuration);
if (!BlobExists(ossClient, containerName, blobName))View on GitHub (pinned to 7ed43b1931)
Solutions
- If overwriting is intended, pass overrideExisting: true to the SaveAsync call so the existence check is skipped.
- If the object is stale, delete it first (DeleteAsync) or confirm it should not be recreated.
- Generate a unique blob name (e.g. append a GUID or timestamp) when each upload must create a distinct object.
- Before saving, call ExistsAsync to branch your logic instead of relying on the throw.
Example fix
// before
await container.SaveAsync("profile.png", stream);
// after (overwrite is desired)
await container.SaveAsync("profile.png", stream, overrideExisting: true);
// after (unique per upload)
await container.SaveAsync($"profile-{Guid.NewGuid():N}.png", stream); Defensive patterns
Strategy: validation
Validate before calling
// Check existence before saving when overwrite is not desired
if (await container.ExistsAsync(blobName))
{
// decide: skip, rename, or explicitly overwrite
return;
}
await container.SaveAsync(blobName, stream); Type guard
if (!args.OverrideExisting && await container.ExistsAsync(blobName)) { /* will throw on save */ } Try / catch
try
{
await container.SaveAsync(blobName, stream);
}
catch (BlobAlreadyExistsException ex)
{
// handle: rename key, prompt user, or retry with overrideExisting: true
} Prevention
- Pass overrideExisting: true whenever the save is an update of existing content.
- Use globally unique blob names (GUID/timestamp) for immutable append-style uploads.
- For retries, verify whether the previous attempt completed before re-saving.
When it happens
Trigger: Calling IBlobContainer.SaveAsync (or the underlying BlobProvider SaveAsync) for a blobName whose AliyunBlobNameCalculator.Calculate result already maps to an existing OSS object, while args.OverrideExisting is false (the default). Also triggered by re-saving after a previous successful PutObject under the same name.
Common situations: Re-uploading an avatar or document whose key is stable (e.g. user-id based), replaying an upload after a transient error that actually completed server-side, or multiple concurrent writers racing to create the same key. Also when a previous run left the object in place and the retry did not set OverrideExisting.
Related errors
- Saving BLOB '{args.BlobName}' does already exists in the con
- Saving BLOB '{args.BlobName}' does already exists in the con
- Blob '{args.BlobName}' already exists in container '{contain
- Saving BLOB '{args.BlobName}' does already exists in the con
- The length of the stream is not available!
AI-assisted analysis of abpframework/abp@7ed43b1931 (2026-08-13).
Data as JSON: /api/errors/4119585ea3bc09a5.
Report an issue: GitHub.