Custom Amazon S3 Storage - "The process cannot access the file"

Mauri Mitchell asked on October 1, 2024 17:11

We have configured a custom storage module according to the follwoing documentation: https://docs.kentico.com/13/custom-development/working-with-physical-files-using-the-api/configuring-file-system-providers/configuring-amazon-s3

Occasionally, we have an issue that results in broken images. It appears that the .meta files are being both read and written to. For example:

An unhandled exception has occurred while executing the request. Message: The process cannot access the file '[Redacted]\App_Data\AmazonTemp__metadata[Redacted]\files\8c\8c410fdc-fe3e-40a1-b351-343fdcb44a07.jpg.meta' because it is being used by another process.

Exception type: System.IO.IOException Stack trace: at Microsoft.Win32.SafeHandles.SafeFileHandle.CreateFile(String fullPath, FileMode mode, FileAccess access, FileShare share, FileOptions options) at Microsoft.Win32.SafeHandles.SafeFileHandle.Open(String fullPath, FileMode mode, FileAccess access, FileShare share, FileOptions options, Int64 preallocationSize, Nullable1 unixCreateMode) at System.IO.Strategies.OSFileStreamStrategy..ctor(String path, FileMode mode, FileAccess access, FileShare share, FileOptions options, Int64 preallocationSize, Nullable1 unixCreateMode) at Amazon.S3.Model.GetObjectResponse.WriteResponseStreamToFileAsync(String filePath, Boolean append, CancellationToken cancellationToken) at CMS.AmazonStorage.S3ObjectInfo.LoadMetadata(String path) at CMS.AmazonStorage.S3ObjectInfo.FetchMetadata() at CMS.AmazonStorage.GetAmazonFileService.GetExternalFile(String filePath) at CMS.Routing.Web.GetExternalFileService.GetFileServiceResult() at CMS.Routing.Web.AdvancedGetFileService.GetActionResultInternal() at CMS.Routing.Web.ActionResultServiceBase.GetActionResult() at CMS.AspNetCore.Platform.Routing.Internal.ActionResultMiddleware.InvokeAsync(HttpContext context) at Microsoft.AspNetCore.Routing.EndpointMiddleware.Invoke(HttpContext httpContext) at Microsoft.AspNetCore.Rewrite.RewriteMiddleware.Invoke(HttpContext context) at Microsoft.AspNetCore.Authorization.AuthorizationMiddleware.Invoke(HttpContext context) at Microsoft.AspNetCore.Authentication.AuthenticationMiddleware.Invoke(HttpContext context) at Microsoft.AspNetCore.Session.SessionMiddleware.Invoke(HttpContext context) at Microsoft.AspNetCore.Session.SessionMiddleware.Invoke(HttpContext context) at Microsoft.AspNetCore.Session.SessionMiddleware.Invoke(HttpContext context) at Microsoft.AspNetCore.Session.SessionMiddleware.Invoke(HttpContext context) at Kentico.Content.Web.Mvc.ContentOutputMiddleware.InvokeAsync(HttpContext context) at Kentico.Web.Mvc.KenticoRequestLocalizationMiddleware.InvokeAsync(HttpContext context) at Kentico.Content.Web.Mvc.PageRedirectionContextMiddleware.InvokeAsync(HttpContext context) at Kentico.Web.Mvc.KenticoRequestEventsMiddleware.InvokeAsync(HttpContext context) at Microsoft.AspNetCore.Diagnostics.StatusCodePagesMiddleware.Invoke(HttpContext context) at Microsoft.AspNetCore.Diagnostics.ExceptionHandlerMiddlewareImpl.g__Awaited|10_0(ExceptionHandlerMiddlewareImpl middleware, HttpContext context, Task task)

We have verified that the Temp files have read/write privileges. We are mapping the following for each site:

StorageHelper.MapStoragePath("[SiteFolder]/media/", mediaProvider); StorageHelper.MapStoragePath("[SiteFolder]/files/", filesProvider); StorageHelper.MapStoragePath("[SiteFolder]/metafiles/", metafilesProvider);

Any suggestions on how to resolve this error are appreciated.

Recent Answers


Juraj Ondrus answered on October 2, 2024 07:32

Are you using the same storage for admin and front end apps? If yes, it is possible that they are accessing the files concurrently. In this case you should disable the web farm sync for media files (and other files mapped to the external storage) in Settings -> Web farm -> Allow synchronization for

Another option is that some security software is blocking the files - I would recommend using Process explorer from Microsoft to see what process is holding the file.

0 votesVote for this answer Mark as a Correct answer

Mauri Mitchell answered on October 2, 2024 18:42

We already had Media Files disabled under "Allow synchronization for". For testing purposes, I unchecked all of the other file types, but that did not resolve the issue.

The lock is temporary. I've confirmed using Process Monitor that IIS Worker Process and System are the only processes attempting to access the file. The Result that leads to the exception is a "SHARING VIOLATION" which occurs on the CreateFile operation by the Worker Process.

Also, the error does not always occur on the media file itself. It occurs on the .meta file that is associated with the media library folder that contains the file. It appears that this .meta file is being generated or overwritten each time a file within that folder is accessed. Since the web page contains multiple images within that folder, I believe this is causing the issue.

Yet, I'm still not sure how to fix it.

0 votesVote for this answer Mark as a Correct answer

Juraj Ondrus answered on October 3, 2024 07:03

isn't it possible that there is some ghost/orphaned app connecting? We would need to know how to reproduce the issue reliably on our end to tell what is going on. There are too many unknown variables and from my experience the environment plays a big part in this game too.

0 votesVote for this answer Mark as a Correct answer

Mauri Mitchell answered on October 8, 2024 22:36

We are on Kentico version 13.0.163. Our live sites are targeting .NET Core 8.0. Our implementation of the custom module is nearly identical to the example provided in the Kentico documentation with the exception that our bucket is not publicly accessible.

https://docs.kentico.com/13/custom-development/working-with-physical-files-using-the-api/configuring-file-system-providers/configuring-amazon-s3

Please let me know what other information would be helpful for recreating the error.

0 votesVote for this answer Mark as a Correct answer

   Please, sign in to be able to submit a new answer.