--- title: ASP.NET Core Module configuration reference author: guardrex description: Learn how to configure the ASP.NET Core Module for hosting ASP.NET Core apps. ms.author: riande ms.custom: mvc ms.date: 11/12/2018 uid: host-and-deploy/aspnet-core-module --- # ASP.NET Core Module configuration reference By [Luke Latham](https://github.com/guardrex), [Rick Anderson](https://twitter.com/RickAndMSFT), [Sourabh Shirhatti](https://twitter.com/sshirhatti), and [Justin Kotalik](https://github.com/jkotalik) This document provides instructions on how to configure the ASP.NET Core Module for hosting ASP.NET Core apps. For an introduction to the ASP.NET Core Module and installation instructions, see the [ASP.NET Core Module overview](xref:fundamentals/servers/aspnet-core-module). ::: moniker range=">= aspnetcore-2.2" ## Hosting model For apps running on .NET Core 2.2 or later, the module supports an in-process hosting model for improved performance compared to reverse-proxy (out-of-process) hosting. For more information, see . In-procsess hosting is opt-in for existing apps, but [dotnet new](/dotnet/core/tools/dotnet-new) templates default to the in-process hosting model for all IIS and IIS Express scenarios. To configure an app for in-process hosting, add the `` property to the app's project file (for example, *MyApp.csproj*) with a value of `inprocess` (out-of-process hosting is set with `outofprocess`): ```xml inprocess ``` The following characteristics apply when hosting in-process: * The [Kestrel server](xref:fundamentals/servers/kestrel) isn't used. A custom implementation, `IISHttpServer` acts as the app's server. * The [requestTimeout attribute](#attributes-of-the-aspnetcore-element) doesn't apply to in-process hosting. * Sharing an app pool among apps isn't supported. Use one app pool per app. * When using [Web Deploy](/iis/publish/using-web-deploy/introduction-to-web-deploy) or manually placing an [app_offline.htm file in the deployment](xref:host-and-deploy/iis/index#locked-deployment-files), the app might not shut down immediately if there's an open connection. For example, a websocket connection may delay app shut down. * The architecture (bitness) of the app and installed runtime (x64 or x86) must match the architecture of the app pool. * If setting up the app's host manually with `WebHostBuilder` (not using [CreateDefaultBuilder](xref:fundamentals/host/web-host#set-up-a-host)) and the app is ever run directly on the Kestrel server (self-hosted), call `UseKestrel` before calling `UseIISIntegration`. If the order is reversed, the host fails to start. * Client disconnects are detected. The [HttpContext.RequestAborted](xref:Microsoft.AspNetCore.Http.HttpContext.RequestAborted*) cancellation token is cancelled when the client disconnects. * `Directory.GetCurrentDirectory()` returns the worker directory of the process started by IIS rather than the application directory (for example, *C:\Windows\System32\inetsrv* for *w3wp.exe*). ### Hosting model changes If the `hostingModel` setting is changed in the *web.config* file (explained in the [Configuration with web.config](#configuration-with-webconfig) section), the module recycles the worker process for IIS. For IIS Express, the module doesn't recycle the worker process but instead triggers a graceful shutdown of the current IIS Express process. The next request to the app spawns a new IIS Express process. ### Process name `Process.GetCurrentProcess().ProcessName` reports `w3wp`/`iisexpress` (in-process) or `dotnet` (out-of-process). ::: moniker-end ## Configuration with web.config The ASP.NET Core Module is configured with the `aspNetCore` section of the `system.webServer` node in the site's *web.config* file. The following *web.config* file is published for a [framework-dependent deployment](/dotnet/articles/core/deploying/#framework-dependent-deployments-fdd) and configures the ASP.NET Core Module to handle site requests: ::: moniker range=">= aspnetcore-2.2" ```xml ``` ::: moniker-end ::: moniker range="< aspnetcore-2.2" ```xml ``` ::: moniker-end The following *web.config* is published for a [self-contained deployment](/dotnet/articles/core/deploying/#self-contained-deployments-scd): ::: moniker range=">= aspnetcore-2.2" ```xml ``` The property is set to `false` to indicate that the settings specified within the [\](/iis/manage/managing-your-configuration-settings/understanding-iis-configuration-delegation#the-concept-of-location) element aren't inherited by apps that reside in a subdirectory of the app. ::: moniker-end ::: moniker range="< aspnetcore-2.2" ```xml ``` ::: moniker-end When an app is deployed to [Azure App Service](https://azure.microsoft.com/services/app-service/), the `stdoutLogFile` path is set to `\\?\%home%\LogFiles\stdout`. The path saves stdout logs to the *LogFiles* folder, which is a location automatically created by the service. For information on IIS sub-application configuration, see . ### Attributes of the aspNetCore element ::: moniker range=">= aspnetcore-2.2" | Attribute | Description | Default | | --------- | ----------- | :-----: | | `arguments` |

Optional string attribute.

Arguments to the executable specified in **processPath**.

| | | `disableStartUpErrorPage` |

Optional Boolean attribute.

If true, the **502.5 - Process Failure** page is suppressed, and the 502 status code page configured in the *web.config* takes precedence.

| `false` | | `forwardWindowsAuthToken` |

Optional Boolean attribute.

If true, the token is forwarded to the child process listening on %ASPNETCORE_PORT% as a header 'MS-ASPNETCORE-WINAUTHTOKEN' per request. It's the responsibility of that process to call CloseHandle on this token per request.

| `true` | | `hostingModel` |

Optional string attribute.

Specifies the hosting model as in-process (`inprocess`) or out-of-process (`outofprocess`).

| `outofprocess` | | `processesPerApplication` |

Optional integer attribute.

Specifies the number of instances of the process specified in the **processPath** setting that can be spun up per app.

†For in-process hosting, the value is limited to `1`.

| Default: `1`
Min: `1`
Max: `100`† | | `processPath` |

Required string attribute.

Path to the executable that launches a process listening for HTTP requests. Relative paths are supported. If the path begins with `.`, the path is considered to be relative to the site root.

| | | `rapidFailsPerMinute` |

Optional integer attribute.

Specifies the number of times the process specified in **processPath** is allowed to crash per minute. If this limit is exceeded, the module stops launching the process for the remainder of the minute.

Not supported with in-process hosting.

| Default: `10`
Min: `0`
Max: `100` | | `requestTimeout` |

Optional timespan attribute.

Specifies the duration for which the ASP.NET Core Module waits for a response from the process listening on %ASPNETCORE_PORT%.

In versions of the ASP.NET Core Module that shipped with the release of ASP.NET Core 2.1 or later, the `requestTimeout` is specified in hours, minutes, and seconds.

Doesn't apply to in-process hosting. For in-process hosting, the module waits for the app to process the request.

| Default: `00:02:00`
Min: `00:00:00`
Max: `360:00:00` | | `shutdownTimeLimit` |

Optional integer attribute.

Duration in seconds that the module waits for the executable to gracefully shutdown when the *app_offline.htm* file is detected.

| Default: `10`
Min: `0`
Max: `600` | | `startupTimeLimit` |

Optional integer attribute.

Duration in seconds that the module waits for the executable to start a process listening on the port. If this time limit is exceeded, the module kills the process. The module attempts to relaunch the process when it receives a new request and continues to attempt to restart the process on subsequent incoming requests unless the app fails to start **rapidFailsPerMinute** number of times in the last rolling minute.

A value of 0 (zero) is **not** considered an infinite timeout.

| Default: `120`
Min: `0`
Max: `3600` | | `stdoutLogEnabled` |

Optional Boolean attribute.

If true, **stdout** and **stderr** for the process specified in **processPath** are redirected to the file specified in **stdoutLogFile**.

| `false` | | `stdoutLogFile` |

Optional string attribute.

Specifies the relative or absolute file path for which **stdout** and **stderr** from the process specified in **processPath** are logged. Relative paths are relative to the root of the site. Any path starting with `.` are relative to the site root and all other paths are treated as absolute paths. Any folders provided in the path must exist in order for the module to create the log file. Using underscore delimiters, a timestamp, process ID, and file extension (*.log*) are added to the last segment of the **stdoutLogFile** path. If `.\logs\stdout` is supplied as a value, an example stdout log is saved as *stdout_20180205194132_1934.log* in the *logs* folder when saved on 2/5/2018 at 19:41:32 with a process ID of 1934.

| `aspnetcore-stdout` | ::: moniker-end ::: moniker range="= aspnetcore-2.1" | Attribute | Description | Default | | --------- | ----------- | :-----: | | `arguments` |

Optional string attribute.

Arguments to the executable specified in **processPath**.

| | | `disableStartUpErrorPage` |

Optional Boolean attribute.

If true, the **502.5 - Process Failure** page is suppressed, and the 502 status code page configured in the *web.config* takes precedence.

| `false` | | `forwardWindowsAuthToken` |

Optional Boolean attribute.

If true, the token is forwarded to the child process listening on %ASPNETCORE_PORT% as a header 'MS-ASPNETCORE-WINAUTHTOKEN' per request. It's the responsibility of that process to call CloseHandle on this token per request.

| `true` | | `processesPerApplication` |

Optional integer attribute.

Specifies the number of instances of the process specified in the **processPath** setting that can be spun up per app.

| Default: `1`
Min: `1`
Max: `100` | | `processPath` |

Required string attribute.

Path to the executable that launches a process listening for HTTP requests. Relative paths are supported. If the path begins with `.`, the path is considered to be relative to the site root.

| | | `rapidFailsPerMinute` |

Optional integer attribute.

Specifies the number of times the process specified in **processPath** is allowed to crash per minute. If this limit is exceeded, the module stops launching the process for the remainder of the minute.

| Default: `10`
Min: `0`
Max: `100` | | `requestTimeout` |

Optional timespan attribute.

Specifies the duration for which the ASP.NET Core Module waits for a response from the process listening on %ASPNETCORE_PORT%.

In versions of the ASP.NET Core Module that shipped with the release of ASP.NET Core 2.1 or later, the `requestTimeout` is specified in hours, minutes, and seconds.

| Default: `00:02:00`
Min: `00:00:00`
Max: `360:00:00` | | `shutdownTimeLimit` |

Optional integer attribute.

Duration in seconds that the module waits for the executable to gracefully shutdown when the *app_offline.htm* file is detected.

| Default: `10`
Min: `0`
Max: `600` | | `startupTimeLimit` |

Optional integer attribute.

Duration in seconds that the module waits for the executable to start a process listening on the port. If this time limit is exceeded, the module kills the process. The module attempts to relaunch the process when it receives a new request and continues to attempt to restart the process on subsequent incoming requests unless the app fails to start **rapidFailsPerMinute** number of times in the last rolling minute.

A value of 0 (zero) is **not** considered an infinite timeout.

| Default: `120`
Min: `0`
Max: `3600` | | `stdoutLogEnabled` |

Optional Boolean attribute.

If true, **stdout** and **stderr** for the process specified in **processPath** are redirected to the file specified in **stdoutLogFile**.

| `false` | | `stdoutLogFile` |

Optional string attribute.

Specifies the relative or absolute file path for which **stdout** and **stderr** from the process specified in **processPath** are logged. Relative paths are relative to the root of the site. Any path starting with `.` are relative to the site root and all other paths are treated as absolute paths. Any folders provided in the path must exist in order for the module to create the log file. Using underscore delimiters, a timestamp, process ID, and file extension (*.log*) are added to the last segment of the **stdoutLogFile** path. If `.\logs\stdout` is supplied as a value, an example stdout log is saved as *stdout_20180205194132_1934.log* in the *logs* folder when saved on 2/5/2018 at 19:41:32 with a process ID of 1934.

| `aspnetcore-stdout` | ::: moniker-end ::: moniker range="<= aspnetcore-2.0" | Attribute | Description | Default | | --------- | ----------- | :-----: | | `arguments` |

Optional string attribute.

Arguments to the executable specified in **processPath**.

| | | `disableStartUpErrorPage` |

Optional Boolean attribute.

If true, the **502.5 - Process Failure** page is suppressed, and the 502 status code page configured in the *web.config* takes precedence.

| `false` | | `forwardWindowsAuthToken` |

Optional Boolean attribute.

If true, the token is forwarded to the child process listening on %ASPNETCORE_PORT% as a header 'MS-ASPNETCORE-WINAUTHTOKEN' per request. It's the responsibility of that process to call CloseHandle on this token per request.

| `true` | | `processesPerApplication` |

Optional integer attribute.

Specifies the number of instances of the process specified in the **processPath** setting that can be spun up per app.

| Default: `1`
Min: `1`
Max: `100` | | `processPath` |

Required string attribute.

Path to the executable that launches a process listening for HTTP requests. Relative paths are supported. If the path begins with `.`, the path is considered to be relative to the site root.

| | | `rapidFailsPerMinute` |

Optional integer attribute.

Specifies the number of times the process specified in **processPath** is allowed to crash per minute. If this limit is exceeded, the module stops launching the process for the remainder of the minute.

| Default: `10`
Min: `0`
Max: `100` | | `requestTimeout` |

Optional timespan attribute.

Specifies the duration for which the ASP.NET Core Module waits for a response from the process listening on %ASPNETCORE_PORT%.

In versions of the ASP.NET Core Module that shipped with the release of ASP.NET Core 2.0 or earlier, the `requestTimeout` must be specified in whole minutes only, otherwise it defaults to 2 minutes.

| Default: `00:02:00`
Min: `00:00:00`
Max: `360:00:00` | | `shutdownTimeLimit` |

Optional integer attribute.

Duration in seconds that the module waits for the executable to gracefully shutdown when the *app_offline.htm* file is detected.

| Default: `10`
Min: `0`
Max: `600` | | `startupTimeLimit` |

Optional integer attribute.

Duration in seconds that the module waits for the executable to start a process listening on the port. If this time limit is exceeded, the module kills the process. The module attempts to relaunch the process when it receives a new request and continues to attempt to restart the process on subsequent incoming requests unless the app fails to start **rapidFailsPerMinute** number of times in the last rolling minute.

| Default: `120`
Min: `0`
Max: `3600` | | `stdoutLogEnabled` |

Optional Boolean attribute.

If true, **stdout** and **stderr** for the process specified in **processPath** are redirected to the file specified in **stdoutLogFile**.

| `false` | | `stdoutLogFile` |

Optional string attribute.

Specifies the relative or absolute file path for which **stdout** and **stderr** from the process specified in **processPath** are logged. Relative paths are relative to the root of the site. Any path starting with `.` are relative to the site root and all other paths are treated as absolute paths. Any folders provided in the path must exist in order for the module to create the log file. Using underscore delimiters, a timestamp, process ID, and file extension (*.log*) are added to the last segment of the **stdoutLogFile** path. If `.\logs\stdout` is supplied as a value, an example stdout log is saved as *stdout_20180205194132_1934.log* in the *logs* folder when saved on 2/5/2018 at 19:41:32 with a process ID of 1934.

| `aspnetcore-stdout` | ::: moniker-end ### Setting environment variables Environment variables can be specified for the process in the `processPath` attribute. Specify an environment variable with the `environmentVariable` child element of an `environmentVariables` collection element. Environment variables set in this section take precedence over system environment variables. The following example sets two environment variables. `ASPNETCORE_ENVIRONMENT` configures the app's environment to `Development`. A developer may temporarily set this value in the *web.config* file in order to force the [Developer Exception Page](xref:fundamentals/error-handling) to load when debugging an app exception. `CONFIG_DIR` is an example of a user-defined environment variable, where the developer has written code that reads the value on startup to form a path for loading the app's configuration file. ::: moniker range=">= aspnetcore-2.2" ```xml ``` ::: moniker-end ::: moniker range="< aspnetcore-2.2" ```xml ``` ::: moniker-end > [!WARNING] > Only set the `ASPNETCORE_ENVIRONMENT` environment variable to `Development` on staging and testing servers that aren't accessible to untrusted networks, such as the Internet. ## app_offline.htm If a file with the name *app_offline.htm* is detected in the root directory of an app, the ASP.NET Core Module attempts to gracefully shutdown the app and stop processing incoming requests. If the app is still running after the number of seconds defined in `shutdownTimeLimit`, the ASP.NET Core Module kills the running process. While the *app_offline.htm* file is present, the ASP.NET Core Module responds to requests by sending back the contents of the *app_offline.htm* file. When the *app_offline.htm* file is removed, the next request starts the app. ::: moniker range=">= aspnetcore-2.2" When using the out-of-process hosting model, the app might not shut down immediately if there's an open connection. For example, a websocket connection may delay app shut down. ::: moniker-end ## Start-up error page ::: moniker range=">= aspnetcore-2.2" Both in-process and out-of-process hosting produce custom error pages when they fail to start the app. If the ASP.NET Core Module fails to find either the in-process or out-of-process request handler, a *500.0 - In-Process/Out-Of-Process Handler Load Failure* status code page appears. For in-process hosting if the ASP.NET Core Module fails to start the app, a *500.30 - Start Failure* status code page appears. For out-of-process hosting if the ASP.NET Core Module fails to launch the backend process or the backend process starts but fails to listen on the configured port, a *502.5 - Process Failure* status code page appears. To suppress this page and revert to the default IIS 5xx status code page, use the `disableStartUpErrorPage` attribute. For more information on configuring custom error messages, see [HTTP Errors \](/iis/configuration/system.webServer/httpErrors/). ::: moniker-end ::: moniker range="< aspnetcore-2.2" If the ASP.NET Core Module fails to launch the backend process or the backend process starts but fails to listen on the configured port, a *502.5 - Process Failure* status code page appears. To suppress this page and revert to the default IIS 502 status code page, use the `disableStartUpErrorPage` attribute. For more information on configuring custom error messages, see [HTTP Errors \](/iis/configuration/system.webServer/httpErrors/). ![502.5 Process Failure Status Code Page](aspnet-core-module/_static/ANCM-502_5.png) ::: moniker-end ## Log creation and redirection The ASP.NET Core Module redirects stdout and stderr console output to disk if the `stdoutLogEnabled` and `stdoutLogFile` attributes of the `aspNetCore` element are set. Any folders in the `stdoutLogFile` path must exist in order for the module to create the log file. The app pool must have write access to the location where the logs are written (use `IIS AppPool\` to provide write permission). Logs aren't rotated, unless process recycling/restart occurs. It's the responsibility of the hoster to limit the disk space the logs consume. Using the stdout log is only recommended for troubleshooting app startup issues. Don't use the stdout log for general app logging purposes. For routine logging in an ASP.NET Core app, use a logging library that limits log file size and rotates logs. For more information, see [third-party logging providers](xref:fundamentals/logging/index#third-party-logging-providers). A timestamp and file extension are added automatically when the log file is created. The log file name is composed by appending the timestamp, process ID, and file extension (*.log*) to the last segment of the `stdoutLogFile` path (typically *stdout*) delimited by underscores. If the `stdoutLogFile` path ends with *stdout*, a log for an app with a PID of 1934 created on 2/5/2018 at 19:42:32 has the file name *stdout_20180205194132_1934.log*. ::: moniker range=">= aspnetcore-2.2" If `stdoutLogEnabled` is false, errors that occur on app startup are captured and emitted to the event log up to 30 KB. After startup, all additional logs are discarded. ::: moniker-end The following sample `aspNetCore` element configures stdout logging for an app hosted in Azure App Service. A local path or network share path is acceptable for local logging. Confirm that the AppPool user identity has permission to write to the path provided. ::: moniker range=">= aspnetcore-2.2" ```xml ``` ::: moniker-end ::: moniker range="< aspnetcore-2.2" ```xml ``` ::: moniker-end ::: moniker range=">= aspnetcore-2.2" ## Enhanced diagnostic logs The ASP.NET Core Module provides is configurable to provide enhanced diagnostics logs. Add the `` element to the `` element in *web.config*. Setting the `debugLevel` to `TRACE` exposes a higher fidelity of diagnostic information: ```xml ``` Debug level (`debugLevel`) values can include both the level and the location. Levels (in order from least to most verbose): * ERROR * WARNING * INFO * TRACE Locations (multiple locations are permitted): * CONSOLE * EVENTLOG * FILE The handler settings can also be provided via environment variables: * `ASPNETCORE_MODULE_DEBUG_FILE` – Path to the debug log file. (Default: *aspnetcore-debug.log*) * `ASPNETCORE_MODULE_DEBUG` – Debug level setting. > [!WARNING] > Do **not** leave debug logging enabled in the deployment for longer than required to troubleshoot an issue. The size of the log isn't limited. Leaving the debug log enabled can exhaust the available disk space and crash the server or app service. ::: moniker-end See [Configuration with web.config](#configuration-with-webconfig) for an example of the `aspNetCore` element in the *web.config* file. ## Proxy configuration uses HTTP protocol and a pairing token ::: moniker range=">= aspnetcore-2.2" *Only applies to out-of-process hosting.* ::: moniker-end The proxy created between the ASP.NET Core Module and Kestrel uses the HTTP protocol. Using HTTP is a performance optimization, where the traffic between the module and Kestrel takes place on a loopback address off of the network interface. There's no risk of eavesdropping the traffic between the module and Kestrel from a location off of the server. A pairing token is used to guarantee that the requests received by Kestrel were proxied by IIS and didn't come from some other source. The pairing token is created and set into an environment variable (`ASPNETCORE_TOKEN`) by the module. The pairing token is also set into a header (`MSAspNetCoreToken`) on every proxied request. IIS Middleware checks each request it receives to confirm that the pairing token header value matches the environment variable value. If the token values are mismatched, the request is logged and rejected. The pairing token environment variable and the traffic between the module and Kestrel aren't accessible from a location off of the server. Without knowing the pairing token value, an attacker can't submit requests that bypass the check in the IIS Middleware. ## ASP.NET Core Module with an IIS Shared Configuration The ASP.NET Core Module installer runs with the privileges of the **SYSTEM** account. Because the local system account doesn't have modify permission for the share path used by the IIS Shared Configuration, the installer hits an access denied error when attempting to configure the module settings in *applicationHost.config* on the share. When using an IIS Shared Configuration, follow these steps: 1. Disable the IIS Shared Configuration. 1. Run the installer. 1. Export the updated *applicationHost.config* file to the share. 1. Re-enable the IIS Shared Configuration. ## Module version and Hosting Bundle installer logs To determine the version of the installed ASP.NET Core Module: 1. On the hosting system, navigate to *%windir%\System32\inetsrv*. 1. Locate the *aspnetcore.dll* file. 1. Right-click the file and select **Properties** from the contextual menu. 1. Select the **Details** tab. The **File version** and **Product version** represent the installed version of the module. The Hosting Bundle installer logs for the module are found at *C:\\Users\\%UserName%\\AppData\\Local\\Temp*. The file is named *dd_DotNetCoreWinSvrHosting__\_000_AspNetCoreModule_x64.log*. ## Module, schema, and configuration file locations ### Module **IIS (x86/amd64):** * %windir%\System32\inetsrv\aspnetcore.dll * %windir%\SysWOW64\inetsrv\aspnetcore.dll ::: moniker range=">= aspnetcore-2.2" * %ProgramFiles%\IIS\Asp.Net Core Module\V2\aspnetcorev2.dll * %ProgramFiles(x86)%\IIS\Asp.Net Core Module\V2\aspnetcorev2.dll ::: moniker-end **IIS Express (x86/amd64):** * %ProgramFiles%\IIS Express\aspnetcore.dll * %ProgramFiles(x86)%\IIS Express\aspnetcore.dll ::: moniker range=">= aspnetcore-2.2" * %ProgramFiles%\IIS Express\Asp.Net Core Module\V2\aspnetcorev2.dll * %ProgramFiles(x86)%\IIS Express\Asp.Net Core Module\V2\aspnetcorev2.dll ::: moniker-end ### Schema **IIS** * %windir%\System32\inetsrv\config\schema\aspnetcore_schema.xml ::: moniker range=">= aspnetcore-2.2" * %windir%\System32\inetsrv\config\schema\aspnetcore_schema_v2.xml ::: moniker-end **IIS Express** * %ProgramFiles%\IIS Express\config\schema\aspnetcore_schema.xml ::: moniker range=">= aspnetcore-2.2" * %ProgramFiles%\IIS Express\config\schema\aspnetcore_schema_v2.xml ::: moniker-end ### Configuration **IIS** * %windir%\System32\inetsrv\config\applicationHost.config **IIS Express** * %ProgramFiles%\IIS Express\config\templates\PersonalWebServer\applicationHost.config The files can be found by searching for *aspnetcore* in the *applicationHost.config* file.