OrchardCMS/OrchardCore · error · FileStoreException
Error while copying file
Error message
Error while copying file '{srcPath}'; copy operation failed with status {properties.Value.CopyStatus} and description {properties.Value.CopyStatusDescription}. What it means
After starting an asynchronous server-side copy (StartCopyFromUriAsync), CopyFileAsync polls the destination blob's properties and throws FileStoreException if CopyStatus is not Success (e.g. Failed or Aborted), including Azure's CopyStatusDescription. The copy is a server-side storage operation, so failure details come from the storage service.
Solutions
- Inspect CopyStatusDescription in the message for Azure's failure reason.
- If copying across accounts, ensure the source SAS is valid long enough or use a stored access policy.
- Retry the copy operation; transient failures often succeed on retry.
- For large or critical copies, poll CopyStatus in a loop instead of relying on the fixed 250 ms delay.
Example fix
// before
await _fileStore.CopyFileAsync(srcPath, dstPath);
// after
try
{
await _fileStore.CopyFileAsync(srcPath, dstPath);
}
catch (FileStoreException ex)
{
_logger.LogError(ex, "Blob copy failed for {Src} -> {Dst}; will retry", srcPath, dstPath);
await _fileStore.TryDeleteFileAsync(dstPath);
await _fileStore.CopyFileAsync(srcPath, dstPath);
} Defensive patterns
Strategy: retry
Try / catch
try
{
await _fileStore.CopyFileAsync(srcPath, dstPath);
}
catch (FileStoreException ex) when (ex.Message.Contains("copy operation failed"))
{
_logger.LogWarning(ex, "Async blob copy failed for {Src}; retrying", srcPath);
await _fileStore.TryDeleteFileAsync(dstPath);
await Task.Delay(TimeSpan.FromSeconds(2));
await _fileStore.CopyFileAsync(srcPath, dstPath);
} Prevention
- Use long-lived or stored-access-policy SAS when copying across accounts.
- Allow extra time for large blobs; server-side copies are asynchronous.
- Retry copies; most status failures are transient or permission-related.
- Read CopyStatusDescription in the message for Azure's root cause.
When it happens
Trigger: StartCopyFromUriAsync completed but the resulting copy failed: source blob modified or permissions revoked mid-copy (SAS expired), size limits exceeded, or the copy was aborted; detected when properties report a non-Success CopyStatus after the polling delay.
Common situations: Copies from another storage account using short-lived SAS tokens that expire before the copy finishes; very large blobs copied across accounts; storage account failovers; throttling during copy.
Understand the failure class
Background: "failed to write file", "Could not save figure", "Error saving remote file" — file write failed: causes and fixes across languages and libraries — this error's family across 38 libraries.
Related errors
- Cannot copy file ' ' because a file already exists in the…
- Cannot copy file ' ' because it does not exist.
- Cannot delete directory
- Cannot delete the root directory.
- Cannot move file ' ' to ' '.
AI-assisted analysis of OrchardCMS/OrchardCore@4306c0717f (2026-09-13).
Data as JSON: /api/errors/824e2b1bab477a5f.
Report an issue: GitHub.
Appendix: source
Thrown at src/OrchardCore/OrchardCore.FileStorage.AzureBlob/BlobFileStore.cs:616
throw new FileStoreException($"Cannot copy file '{srcPath}' because a file already exists in the new path '{dstPath}'.");
}
await newBlob.StartCopyFromUriAsync(oldBlob.Uri);
await Task.Delay(250);
var properties = await newBlob.GetPropertiesAsync();
while (properties.Value.CopyStatus == CopyStatus.Pending)
{
await Task.Delay(250);
// Need to fetch properties or CopyStatus will never update.
properties = await newBlob.GetPropertiesAsync();
}
if (properties.Value.CopyStatus != CopyStatus.Success)
{
throw new FileStoreException($"Error while copying file '{srcPath}'; copy operation failed with status {properties.Value.CopyStatus} and description {properties.Value.CopyStatusDescription}.");
}
}
catch (FileStoreException)
{
throw;
}
catch (Exception ex)
{
throw new FileStoreException($"Cannot copy file '{srcPath}' to '{dstPath}'.", ex);
}
}
public async Task<Stream> GetFileStreamAsync(string path)
{
try
{
var blob = GetBlobReference(path);
View on GitHub (pinned to 4306c0717f)