dotnet / dotnet/aspnetcore

Deleting app_offline.htm does not restart ASP.NET Core app hosted on IIS

Open
#53,894 8 comments 1 reaction 0 assignees View on GitHub
area-networking feature-iis question
Dominant language
C#
Stars
38.4k
Forks
10.9k
Avg merge
2d 6h
Merged PRs (30d)
290

Description

### Is there an existing issue for this?

- [x] I have searched the existing issues

### Describe the bug

I genuinly don't know if this is a bug, but the observed behavior was a bit odd, and even after extensive research I couldn't find out if it's intended or not.

Given an arbitrary ASP.NET Core 8 application that is hosted via the in-process model behind an IIS 10 site. Given also the fact, that the environment (app pool, site, application,...) is configured to keep the app alive permanently and preload it, therefore
- Set the corresponding application pool to "Always running"
- Set the idle timeout to 0:00
- Enable preload
- Set "serverAutoStart" to "true" on the corresponding site

So when a file named 'app_offline.htm' is placed in the application root, the ANCM picks that up and serves it along with a status of HTTP 503. The application logs show, that it was asked to [shut down gracefully](https://learn.microsoft.com/en-us/aspnet/core/host-and-deploy/app-offline?view=aspnetcore-8.0).

Now when deleting 'app_offline.htm' I expected the app to be started again immediately. But the logs show, that it is not started until the first request arrives, so basically that's the behavior you would expect on an app that does has preloading disabled.

I guess that behavior is fine for most web applications, but it actually is quite a problem for applications that have some background workers, like Message Bus listeners, etc. since those would not be started either.

### Expected Behavior

I would have expected, that deleting 'app_offline.htm' would cause the app to restart immediately, and not on the first arriving request.

### Steps To Reproduce
I tested it with an app that hosts a background service, just to see when the service will actually be started.
```cs
var builder = WebApplication.CreateBuilder(args);
builder.Services.AddHostedService();

var app = builder.Build();

app.MapGet("/", async (r) =>
{
r.Response.StatusCode = 200;
await r.Response.WriteAsync("Test");
});

app.Run();

public class UpDownService(ILogger logger) : IHostedService
{
public Task StartAsync(CancellationToken cancellationToken)
{
logger.LogWarning("This service has been started.");
return Task.CompletedTask;
}

public Task StopAsync(CancellationToken cancellationToken)
{
logger.LogWarning("This service has been stopped.");
return Task.CompletedTask;
}
}
```

The corresponding web.config:
```xml






```

The simplified logs would now look something like that - note that lines starting with '>' are not visible in the logs:
```txt
This service has been started.
> app_offline.htm was placed in application root
This service has been stopped.
> app_offline.htm was deleted from application root
> Request to "/" arrives
This service has been started.
```

and the relevant parts from applicationHost.config:
```xml




...

...



```

### Exceptions (if any)
No exceptions

### .NET Version

.NET 8.0
ASP.NET Core 8
.NET SDK 8.0.100

EDIT: Sorry, I opened the issue too early by accident.

Contributor guide

Open the contributing guide

Assessment

This issue has not been assessed yet.

Get new issues in your inbox

A short digest of beginner-friendly GitHub issues.