OrchardCMS/OrchardCore · error · FileStoreException
Cannot delete file ' '.
Error message
Cannot delete file '{path}'. What it means
BlobFileStore.TryDeleteFileAsync calls DeleteIfExistsAsync on the blob client; any exception from the delete call is wrapped in a FileStoreException 'Cannot delete file {path}'. A missing blob is not an error (the method returns false), so this indicates a real failure reaching or authorizing the delete. It is also invoked from MoveFileAsync, where a failure during the move's delete step surfaces here.
Solutions
- Inspect the inner exception status: 403 → grant delete permission or check immutability/legal-hold policy; 409/412 → blob is leased, release the lease or retry later.
- Verify the configured identity has Storage Blob Data Contributor (or delete rights) on the container.
- Handle the false return as 'file was not there' — only treat the exception as a genuine failure.
- For MoveFileAsync failures, check whether the destination copy succeeded and clean up/redo the move idempotently.
Example fix
// before
await fileStore.TryDeleteFileAsync(oldPath); // may throw if lease held
// after
try
{
await fileStore.TryDeleteFileAsync(oldPath);
}
catch (FileStoreException) when (await fileStore.GetFileInfoAsync(oldPath) == null)
{
// already gone; ignore
} Defensive patterns
Strategy: try-catch
Validate before calling
var file = await fileStore.GetFileInfoAsync(path);
if (file == null)
{
return true; // nothing to delete — treat as success/no-op
} Try / catch
try
{
await fileStore.TryDeleteFileAsync(path);
}
catch (FileStoreException ex)
when ((ex.InnerException as RequestFailedException)?.Status is 409 or 412 or 403)
{
logger.LogWarning(ex, "Blob delete blocked (lease/hold/permissions) for {Path}", path);
// schedule retry after lease release or fix policy/permissions
} Prevention
- Handle false (missing blob) and thrown exceptions as distinct outcomes.
- Check for immutability policies/legal holds and active leases before deleting.
- Grant the identity Storage Blob Data Contributor for delete scenarios.
- In MoveFileAsync flows, make moves idempotent so a failed delete of the source can be retried.
When it happens
Trigger: Calling TryDeleteFileAsync(path) when DeleteIfExistsAsync throws — 403 authorization failure (no delete permission / immutable blob), 412 lease conflict (blob locked by a lease), 409 snapshot-in-progress, network/service errors, or from MoveFileAsync when deleting the source after copy fails.
Common situations: Blobs with active leases (another process holds a lease); immutability policies / legal hold on the container; identity lacking Storage Blob Data Contributor delete rights; transient Azure errors; concurrent MoveFileAsync operations contending on the same blob.
Understand the failure class
Background: "File not found" and ENOENT errors: why libraries can't find a file that should exist — this error's family across 50 libraries.
Related errors
- Cannot get file info with path
- Cannot get directory info with path
- Cannot get directory content with path
- Cannot create directory
- Cannot create directory because the path
AI-assisted analysis of OrchardCMS/OrchardCore@4306c0717f (2026-09-13).
Data as JSON: /api/errors/63fb742b89f29c12.
Report an issue: GitHub.
Appendix: source
Thrown at src/OrchardCore/OrchardCore.FileStorage.AzureBlob/BlobFileStore.cs:473
throw;
}
catch (Exception ex)
{
throw new FileStoreException($"Cannot create directory '{path}'.", ex);
}
}
public async Task<bool> TryDeleteFileAsync(string path)
{
try
{
var blob = GetBlobReference(path);
return await blob.DeleteIfExistsAsync();
}
catch (Exception ex)
{
throw new FileStoreException($"Cannot delete file '{path}'.", ex);
}
}
public async Task<bool> TryDeleteDirectoryAsync(string path)
{
await EnsureCapabilitiesAsync();
if (_capabilities?.HasHierarchicalNamespace == true)
{
try
{
if (string.IsNullOrEmpty(path))
{
throw new FileStoreException("Cannot delete the root directory.");
}
var prefix = this.Combine(_basePrefix, path);
var directoryClient = _dataLakeFileSystemClient.GetDirectoryClient(prefix);View on GitHub (pinned to 4306c0717f)