OrchardCMS/OrchardCore · error · FileStoreException

Error while copying file

Error message

Error while copying file '{srcPath}': {ex.Message}

What it means

AmazonS3Exception thrown by CopyObjectAsync during CopyFileAsync is wrapped in a FileStoreException that appends the S3 error message and preserves the inner exception. It signals S3 rejected the copy request itself (auth, permissions, limits, connectivity).

Solutions

  1. Inspect the inner AmazonS3Exception message/error code and fix the underlying S3 permission or configuration issue.
  2. Grant IAM permissions for s3:GetObject on source and s3:PutObject on destination.
  3. For Glacier/archived objects, restore them first or use a multipart/manual copy via streams.
  4. Use a multipart copy or stream-based copy for objects larger than 5 GB.

Example fix

// before
await fileStore.CopyFileAsync(srcPath, dstPath); // throws with no context handling

// after
try
{
    await fileStore.CopyFileAsync(srcPath, dstPath);
}
catch (FileStoreException ex)
{
    _logger.LogError(ex, "Copy of '{Src}' to '{Dst}' failed: {Msg}", srcPath, dstPath, ex.Message);
    throw;
}
Defensive patterns

Strategy: try-catch

Try / catch

try
{
    await fileStore.CopyFileAsync(srcPath, dstPath);
}
catch (FileStoreException ex)
{
    var s3Message = ex.InnerException?.Message ?? ex.Message;
    _logger.LogError("Copy failed, S3 said: {S3Message}", s3Message);
    throw;
}

Prevention

When it happens

Trigger: CopyFileAsync/MoveFileAsync when CopyObjectAsync throws: AccessDenied, InvalidObjectState (archive storage class), missing kms permissions, object too large for server-side copy, network failure.

Common situations: IAM lacks s3:PutObject on destination, source object in GLACIER storage class, KMS-encrypted objects without kms:Decrypt/Encrypt grants, 5GB server-side copy limit exceeded.

Related errors


AI-assisted analysis of OrchardCMS/OrchardCore@4306c0717f (2026-09-13). Data as JSON: /api/errors/9386ef32bbb91f11. Report an issue: GitHub.

Appendix: source

Thrown at src/OrchardCore/OrchardCore.FileStorage.AmazonS3/AwsFileStorage.cs:247

            }

            var copyObjectResponse = await _amazonS3Client.CopyObjectAsync(new CopyObjectRequest
            {
                SourceBucket = _options.BucketName,
                SourceKey = this.Combine(_basePrefix, srcPath),
                DestinationBucket = _options.BucketName,
                DestinationKey = this.Combine(_basePrefix, dstPath),
            });

            if (!copyObjectResponse.IsSuccessful())
            {
                throw new FileStoreException($"Error while copying file '{srcPath}'");
            }

        }
        catch (AmazonS3Exception ex)
        {
            throw new FileStoreException($"Error while copying file '{srcPath}': {ex.Message}", ex);
        }
    }

    public Task<Stream> GetFileStreamAsync(string path)
    {
        try
        {
            var transferUtility = new TransferUtility(_amazonS3Client);
            return transferUtility.OpenStreamAsync(_options.BucketName, this.Combine(_basePrefix, path));
        }
        catch (AmazonS3Exception ex) when (ex.StatusCode == HttpStatusCode.NotFound)
        {
            throw new FileStoreException($"Cannot get file stream because the file '{path}' does not exist.");
        }
        catch (AmazonS3Exception ex)
        {
            throw new FileStoreException($"Error getting file stream for '{path}': {ex.Message}", ex);
        }

View on GitHub (pinned to 4306c0717f)