Solving the Azure DevOps release error code: error_file_in_use

In this short post let’s take care of an annoying error in Azure DevOps Release – Azure App Service Deploy task.

Error: Error Code: ERROR_FILE_IN_USE
More Information: Web Deploy cannot modify the file 'webapi20210902.txt' on the destination because it is locked by an external process.  In order to allow the publish operation to succeed, you may need to either restart your application to release the lock, or use the AppOffline rule handler for .Net applications on your next publish attempt.  Learn more at: http://go.microsoft.com/fwlink/?LinkId=221672#ERROR_FILE_IN_USE.
Error: The process cannot access 'C:\home\site\wwwroot\logs\webapi20210902.txt' because it is being used by another process.
   at Microsoft.Web.Deployment.NativeMethods.RaiseIOExceptionFromErrorCode(Win32ErrorCode errorCode, String maybeFullPath)
   at Microsoft.Web.Deployment.FileEx.Delete(String path)
   at Microsoft.Web.Deployment.FilePathProviderBase.Delete(Boolean whatIf)
Error count: 1.

The problem is that the new version of the application cannot be released, because the log file is locked. What was also interesting is the fact that every time retrying the task did help.

The Azure App Service Deploy task has an additional setting called Take App Offline. You can locate this setting in the Additional Deployment Options section. But it didn’t help in my case. Actually, modifying any settings in the task didn’t help. The problem was lying in the application itself. More specifically, in logger.

Solution

I am presenting the solution that worked for me, and I also hope it can help you (let me know in the comment if you had this specific problem).

The problem is really simple. Serilog (the logger of choice for my project) didn’t release the handle to the log file automatically when the application was shut down. Adding Log.CloseAndFlush into the Main method’s finally block solves that issue.

public static void Main(string[] args)
        {
            try
            {
                var configuration = new ConfigurationBuilder()
                    .SetBasePath(Directory.GetCurrentDirectory())
                    .AddJsonFile("appsettings.json")
                    .Build();

                var instrumentationKey = configuration.GetValue<string>("ApplicationInsights:InstrumentationKey");

                Log.Logger = new LoggerConfiguration()
                    .MinimumLevel.Debug()
                    .MinimumLevel.Override("Microsoft", LogEventLevel.Information)
                    .Enrich.FromLogContext()
                    .WriteTo.File("logs\\webapi.txt", rollingInterval: RollingInterval.Day)
                    .WriteTo.Console(theme: AnsiConsoleTheme.Code)
                    .WriteTo.ApplicationInsights(
                        new TelemetryConfiguration
                            {InstrumentationKey = !string.IsNullOrEmpty(instrumentationKey) ? instrumentationKey : ""},
                        TelemetryConverter.Traces)
                    .CreateLogger();

                CreateHostBuilder(args).Build().Run();
            }
            finally
            {
                Log.CloseAndFlush();
            }

Previously I didn’t use try / finally block here. Adding the block fixed the issue with the locked file (ERROR_FILES_IN_USE).

Let's stay in touch!