IIS application initialization - troubleshooting

This post is the continuation of IIS application initialization - setup and goes deeper into the analysis of possible problems with the use of the IIS application Initialization.

There are many reasons why the application initialization feature may fail. If the actual process is not logged, you may not even notice that the initialization was not executed as desired. The problem is that the actual application has not been started yet. Therefore the error analysis is not trivial.

Analyzing with PerfView

But you can track down the errors relatively quickly with PerfView. If you are unfamiliar with PerfView, there are PerfView video tutorials on Channel9.

To trace the application initialization of your web site, select the “Collect” item in the main menu and then choose “Collect”, or press ALT+C (click here for more details). The only thing to consider now is the use of the Microsoft-Windows-IIS ETW Provider by selecting the IIS checkbox.

Perfview Collect IIS Events

Start a trace with Start Collection. Now, go to the IIS Manager and restart (start/stop) your IIS App Pool or simply press “Recycle” in the right pane under Application Pool Tasks. In Perfview you can stop the collection and double click on the Events node

Perfview Analyze IIS Events

The events viewer should now be displayed. It makes sense to filter the events by iis

Perfview Analyze IIS Events

HttpStatus 405 - Method Not Allowed

The application initialization module calls the endpoint specified under initializationPage via HTTP GET request.

<?xml version="1.0" encoding="utf-8"?>
<configuration>
  <location path="." inheritInChildApplications="false">
    <system.webServer>
      <applicationInitialization doAppInitAfterRestart="true" skipManagedModules="true">
        <add initializationPage="/api/init/start" />
      </applicationInitialization>
    </system.webServer>
  </location>
</configuration>

If the controller action does not allow a HTTP GET request, then a 405 Method Not Allowed is returned from the controller. Look in PerfView for HttpStatus 405 events like this:

Perfview 405 Method Not Allowed Therefore, the initialization routine must be able to be called via HTTP GET request. This is usually configured with the HttpGetAttribute applied directly on the action

[ApiController]
public class InitController : ControllerBase
{
    private readonly ILogger<InitController> _logger;
    public InitController(ILogger<InitController> logger)
    {
        _logger = logger;
    }

    [HttpGet]
    [Route("api/init/start")]
    public IActionResult AppInit()
    {
        _logger.LogInformation("app initializer");
        return Ok();
    }
}

HttpStatus 401 - Unauthorized

Another common problem is the authentication of http requests. Within companies, windows authentication is often used in the intranet. however, IIS application Initialization only works with endpoints that also allow anonymous calls. For this purpose, both the web server and the application must be configured accordingly.

In the case of IIS, anonymous authentication must be enabled. In addition, the API must also allow an anonymous call. This is done with the AllowAnonymous-Attribute applied on the corresponding controller action.

[ApiController]
public class InitController : ControllerBase
{
    private readonly ILogger<InitController> _logger;
    public InitController(ILogger<InitController> logger)
    {
        _logger = logger;
    }

    [HttpGet]
    [Route("api/init/start")]
    [AllowAnonymous]
    public IActionResult AppInit()
    {
        _logger.LogInformation("app initializer");
        return Ok();
    }
}

If the controller action does not allow a Anonymous requests, then a 401 Unauthorized is returned from the controller. Look in PerfView for HttpStatus 401 events like this: Perfview 401 Unauthorized

HttpStatus 301 - Web site requires SSL

Usually websites in IIS are configured with an HTTP to HTTPS rule. This means that all HTTP requests are automatically redirected to HTTPS. This is usually configured using the URL Rewrite module. An exemplary configuration of such a rule could look like this:

<?xml version="1.0" encoding="utf-8"?>
<configuration>
    <system.webServer>
      <rewrite>
        <rules>
          <rule name="HTTP to HTTPS redirect for all requests" stopProcessing="true">
            <match url="(.*)" />
            <conditions>
              <add input="{HTTPS}" pattern="off" />
            </conditions>
            <action type="Redirect" url="https://{HTTP_HOST}/{R:1}" />
          </rule>
        </rules>
      </rewrite>
    </system.webServer>
</configuration>

Application Initialization module isn’t working for web site configured to require HTTPS only. Look in PerfView for HttpStatus 301 events like this: Perfview HttpStatus 301

The initialization endpoint must be callable with http. For this to work, the existing URL rewrite rule has to be extended to allow http calls from the app initialization module:

<rewrite>
    <rules>
        <rule name="No redirect on warmup request (request from localhost with warmup user agent)"
        stopProcessing="true">
            <match url=".*" />
            <conditions>
                <add input="{HTTP_HOST}" pattern="localhost" />
                <add input="{HTTP_USER_AGENT}" pattern="Initialization" />
            </conditions>
            <action type="Rewrite" url="{URL}" />
        </rule>
        <rule name="HTTP to HTTPS redirect for all requests" stopProcessing="true">
            <match url="(.*)" />
            <conditions>
                <add input="{HTTPS}" pattern="off" />
            </conditions>
            <action type="Redirect" url="https://{HTTP_HOST}/{R:1}" />
        </rule>
    </rules>
</rewrite>

Tip: Also read Application Initialization module fails when web site requires SSL

Conclusion

When using the IIS Application Initialization feature always ensure your web site allows anonymous calls. This means that the corresponding controller action specified in the web.config under initializationPage is marked with the AllowAnonymous attribute. Furthermore, the iis website must allow anonymous authentication.

And finally, it is always a good idea to have the IIS-HttpTracing module installed on your IIS.