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

  1. Inspect CopyStatusDescription in the message for Azure's failure reason.
  2. If copying across accounts, ensure the source SAS is valid long enough or use a stored access policy.
  3. Retry the copy operation; transient failures often succeed on retry.
  4. 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

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


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)