diff --git a/aspnetcore/host-and-deploy/aspnet-core-module.md b/aspnetcore/host-and-deploy/aspnet-core-module.md
index f72fb4f40208..589aed948ec1 100644
--- a/aspnetcore/host-and-deploy/aspnet-core-module.md
+++ b/aspnetcore/host-and-deploy/aspnet-core-module.md
@@ -5,7 +5,8 @@ description: Learn about the ASP.NET Core Module (ANCM) for hosting ASP.NET Core
monikerRange: '>= aspnetcore-2.1'
ms.author: tdykstra
ms.custom: mvc
-ms.date: 03/04/2022
+ms.date: 04/20/2026
+ms.topic: concept-article
uid: host-and-deploy/aspnet-core-module
---
@@ -15,7 +16,7 @@ uid: host-and-deploy/aspnet-core-module
:::moniker range=">= aspnetcore-5.0"
-The ASP.NET Core Module (ANCM) is a native IIS module that plugs into the IIS pipeline, allowing ASP.NET Core applications to work with IIS. Run ASP.NET Core apps with IIS by either:
+The ASP.NET Core Module (ANCM) is a native IIS module that plugs into the IIS pipeline, allowing ASP.NET Core applications to work with IIS. Run ASP.NET Core apps with IIS by either:
* Hosting an ASP.NET Core app inside of the IIS worker process (`w3wp.exe`), called the [in-process hosting model](xref:host-and-deploy/iis/in-process-hosting).
* Forwarding web requests to a backend ASP.NET Core app running the Kestrel server, called the [out-of-process hosting model](xref:host-and-deploy/iis/out-of-process-hosting).
@@ -151,7 +152,7 @@ For instructions on how to install the ASP.NET Core Module, see [Install the .NE
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:
+The following `web.config` file is published for a [framework-dependent deployment](/dotnet/core/deploying/#framework-dependent-deployments-fdd) and configures the ASP.NET Core Module to handle site requests:
```xml
@@ -171,7 +172,7 @@ The following `web.config` file is published for a [framework-dependent deployme
```
-The following *web.config* is published for a [self-contained deployment](/dotnet/articles/core/deploying/#self-contained-deployments-scd):
+The following *web.config* is published for a [self-contained deployment](/dotnet/core/deploying/#self-contained-deployments-scd):
```xml
@@ -190,9 +191,9 @@ The following *web.config* is published for a [self-contained deployment](/dotne
```
-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.
+The property is set to `false` to indicate that apps that reside in a subdirectory of the app don't inherit the settings specified within the [``](/iis/manage/managing-your-configuration-settings/understanding-iis-configuration-delegation#the-concept-of-location) element.
-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.
+When an app is deployed to [Azure App Service](https://azure.microsoft.com/products/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 .
@@ -211,13 +212,13 @@ For information on IIS sub-application configuration, see 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.
When hosting *in-process*: The process is **not** restarted and does **not** use the **rapidFailsPerMinute** setting.
When hosting *out-of-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 are created by the module when the log file is created. 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` |
+| `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. The module creates any folders provided in the path when it creates 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` |
### Set environment variables
Environment variables can be specified for the process in the `processPath` attribute. Specify an environment variable with the `` child element of an `` collection element. Environment variables set in this section take precedence over system environment variables.
-The following example sets two environment variables in `web.config`. `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.
+The following example sets two environment variables in `web.config`. `ASPNETCORE_ENVIRONMENT` configures the app's environment to `Development`. A developer might 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.
```xml
Development
>
> ```
-
+>
> [!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.
@@ -250,7 +251,7 @@ If a file with the name `app_offline.htm` is detected in the root directory of a
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.
-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.
+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 might delay app shut down.
## Start-up error page
@@ -258,15 +259,15 @@ Both in-process and out-of-process hosting produce custom error pages when they
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 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.
+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/).
## 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 are created by the module when the log file is created. The app pool must have write access to the location where the logs are written (use `IIS AppPool\` to provide write permission).
+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. The module creates any folders in the `stdoutLogFile` path when it creates 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.
@@ -274,7 +275,7 @@ 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`.
+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 February 5, 2018 at 19:42:32 has the file name `stdout_20180205194132_1934.log`.
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.
@@ -312,7 +313,7 @@ The ASP.NET Core Module is configurable to provide enhanced diagnostics logs. Ad
```
-Any folders in the path (`logs` in the preceding example) are created by the module when the log file is created. The app pool must have write access to the location where the logs are written (use `IIS AppPool\{APP POOL NAME}`, where the placeholder `{APP POOL NAME}` is the app pool name, to provide write permission).
+The module creates any folders in the path (`logs` in the preceding example) when it creates the log file. The app pool must have write access to the location where the logs are written (use `IIS AppPool\{APP POOL NAME}`, where the placeholder `{APP POOL NAME}` is the app pool name, to provide write permission).
Debug level (`debugLevel`) values can include both the level and the location.
@@ -363,7 +364,7 @@ Configure the managed stack size using the `stackSize` setting in bytes in `web.
The proxy created between the ASP.NET Core Module and Kestrel uses the HTTP protocol. 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 (`MS-ASPNETCORE-TOKEN`) 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, a cyberattacker can't submit requests that bypass the check in the IIS Middleware.
+A pairing token is used to guarantee that IIS proxied the requests received by Kestrel 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 (`MS-ASPNETCORE-TOKEN`) 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, a cyberattacker can't submit requests that bypass the check in the IIS Middleware.
## ASP.NET Core Module with an IIS Shared Configuration
@@ -382,7 +383,7 @@ When the path to the shared configuration isn't on the same machine as the IIS i
1. Export the updated `applicationHost.config` file to the share.
1. Re-enable the IIS Shared Configuration.
-## Module version and Hosting Bundle installer logs
+## version and Hosting Bundle installer logs
To determine the version of the installed ASP.NET Core Module:
@@ -493,7 +494,7 @@ The following characteristics apply when hosting in-process:
* 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.
+* 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 might delay app shut down.
* The architecture (bitness) of the app and installed runtime (x64 or x86) must match the architecture of the app pool.
@@ -568,7 +569,7 @@ For instructions on how to install the ASP.NET Core Module, see [Install the .NE
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:
+The following *web.config* file is published for a [framework-dependent deployment](/dotnet/core/deploying/#framework-dependent-deployments-fdd) and configures the ASP.NET Core Module to handle site requests:
```xml
@@ -588,7 +589,7 @@ The following *web.config* file is published for a [framework-dependent deployme
```
-The following *web.config* is published for a [self-contained deployment](/dotnet/articles/core/deploying/#self-contained-deployments-scd):
+The following *web.config* is published for a [self-contained deployment](/dotnet/core/deploying/#self-contained-deployments-scd):
```xml
@@ -607,9 +608,9 @@ The following *web.config* is published for a [self-contained deployment](/dotne
```
-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.
+The property is set to `false` to indicate that apps that reside in a subdirectory of the app aren't inheriting the settings specified within the [\](/iis/manage/managing-your-configuration-settings/understanding-iis-configuration-delegation#the-concept-of-location) element.
-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.
+When an app is deployed to [Azure App Service](https://azure.microsoft.com/products/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 .
@@ -628,13 +629,13 @@ For information on IIS sub-application configuration, see 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.
When hosting *in-process*: The process is **not** restarted and does **not** use the `rapidFailsPerMinute` setting.
When hosting *out-of-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 are created by the module when the log file is created. 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` |
+| `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. The module creates any folders provided in the path when it creates 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` |
### Setting environment variables
Environment variables can be specified for the process in the `processPath` attribute. Specify an environment variable with the `` child element of an `` 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.
+The following example sets two environment variables. `ASPNETCORE_ENVIRONMENT` configures the app's environment to `Development`. A developer might 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.
```xml
Development
>
> ```
-
+>
> [!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.
@@ -667,7 +668,7 @@ If a file with the name `app_offline.htm` is detected in the root directory of a
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.
-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.
+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 might delay app shut down.
## Start-up error page
@@ -683,7 +684,7 @@ To suppress this page and revert to the default IIS 5xx status code page, use th
## 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 are created by the module when the log file is created. The app pool must have write access to the location where the logs are written (use `IIS AppPool\{APP POOL NAME}` to provide write permission, where the placeholder `{APP POOL NAME}` is the app pool name).
+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. The module creates any folders in the `stdoutLogFile` path when it creates the log file. The app pool must have write access to the location where the logs are written (use `IIS AppPool\{APP POOL NAME}` to provide write permission, where the placeholder `{APP POOL NAME}` is the app pool name).
Logs aren't rotated, unless process recycling/restart occurs. It's the responsibility of the hoster to limit the disk space the logs consume.
@@ -727,7 +728,7 @@ The ASP.NET Core Module is configurable to provide enhanced diagnostics logs. Ad
```
-Folders in the path provided to the `` value (`logs` in the preceding example) aren't created by the module automatically and should pre-exist in the deployment. The app pool must have write access to the location where the logs are written (use `IIS AppPool\{APP POOL NAME}` to provide write permission, where the placeholder `{APP POOL NAME}` is the app pool name).
+The module doesn't automatically create folders in the path provided to the `` value (`logs` in the preceding example) and should pre-exist in the deployment. The app pool must have write access to the location where the logs are written (use `IIS AppPool\{APP POOL NAME}` to provide write permission, where the placeholder `{APP POOL NAME}` is the app pool name).
Debug level (`debugLevel`) values can include both the level and the location.
@@ -760,7 +761,7 @@ See [Configuration with web.config](#configuration-with-webconfig) for an exampl
The proxy created between the ASP.NET Core Module and Kestrel uses the HTTP protocol. 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 (`MS-ASPNETCORE-TOKEN`) 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, a cyberattacker can't submit requests that bypass the check in the IIS Middleware.
+A pairing token is used to guarantee that IIS proxied the requests received by Kestrel 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 (`MS-ASPNETCORE-TOKEN`) 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, a cyberattacker can't submit requests that bypass the check in the IIS Middleware.
## ASP.NET Core Module with an IIS Shared Configuration
@@ -855,7 +856,7 @@ Supported Windows versions:
The module only works with Kestrel. The module is incompatible with [HTTP.sys](xref:fundamentals/servers/httpsys).
-Because ASP.NET Core apps run in a process separate from the IIS worker process, the module also handles process management. The module starts the process for the ASP.NET Core app when the first request arrives and restarts the app if it crashes. This is essentially the same behavior as seen with ASP.NET 4.x apps that run in-process in IIS that are managed by the [Windows Process Activation Service (WAS)](/iis/manage/provisioning-and-managing-iis/features-of-the-windows-process-activation-service-was).
+Because ASP.NET Core apps run in a process separate from the IIS worker process, the module also handles process management. The module starts the process for the ASP.NET Core app when the first request arrives and restarts the app if it crashes. This is essentially the same behavior as seen with ASP.NET 4.x apps that run in-process in IIS that the [Windows Process Activation Service (WAS)](/iis/manage/provisioning-and-managing-iis/features-of-the-windows-process-activation-service-was) manages.
The following diagram illustrates the relationship between IIS, the ASP.NET Core Module, and an app:
@@ -883,7 +884,7 @@ For instructions on how to install the ASP.NET Core Module, see [Install the .NE
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:
+The following *web.config* file is published for a [framework-dependent deployment](/dotnet/core/deploying/#framework-dependent-deployments-fdd) and configures the ASP.NET Core Module to handle site requests:
```xml
@@ -900,7 +901,7 @@ The following *web.config* file is published for a [framework-dependent deployme
```
-The following *web.config* is published for a [self-contained deployment](/dotnet/articles/core/deploying/#self-contained-deployments-scd):
+The following *web.config* is published for a [self-contained deployment](/dotnet/core/deploying/#self-contained-deployments-scd):
```xml
@@ -916,7 +917,7 @@ The following *web.config* is published for a [self-contained deployment](/dotne
```
-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.
+When an app is deployed to [Azure App Service](https://azure.microsoft.com/products/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 .
@@ -943,7 +944,7 @@ Environment variables can be specified for the process in the `processPath` attr
> [!WARNING]
> Environment variables set in this section conflict with system environment variables set with the same name. If an environment variable is set in both the *web.config* file and at the system level in Windows, the value from the *web.config* file becomes appended to the system environment variable value (for example, `ASPNETCORE_ENVIRONMENT: Development;Development`), which prevents the app from starting.
-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.
+The following example sets two environment variables. `ASPNETCORE_ENVIRONMENT` configures the app's environment to `Development`. A developer might 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.
```xml
` to provide write permission).
+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. The module creates any folders in the `stdoutLogFile` path when it creates 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.
@@ -1002,7 +1003,7 @@ For more information on path formats, see [File path formats on Windows systems]
The proxy created between the ASP.NET Core Module and Kestrel uses the HTTP protocol. 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 (`MS-ASPNETCORE-TOKEN`) 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, a cyberattacker can't submit requests that bypass the check in the IIS Middleware.
+A pairing token is used to guarantee that IIS proxied the requests received by Kestrel 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 (`MS-ASPNETCORE-TOKEN`) 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, a cyberattacker can't submit requests that bypass the check in the IIS Middleware.
## ASP.NET Core Module with an IIS Shared Configuration
diff --git a/aspnetcore/host-and-deploy/azure-iis-errors-reference.md b/aspnetcore/host-and-deploy/azure-iis-errors-reference.md
index 56f258585a27..ee1c03ca05c4 100644
--- a/aspnetcore/host-and-deploy/azure-iis-errors-reference.md
+++ b/aspnetcore/host-and-deploy/azure-iis-errors-reference.md
@@ -4,7 +4,8 @@ author: tdykstra
description: Provides troubleshooting advice for the most common errors when hosting ASP.NET Core apps on Azure Apps Service and IIS.
monikerRange: '>= aspnetcore-2.1'
ms.author: tdykstra
-ms.date: 7/23/2024
+ms.date: 04/21/2026
+ms.topic: concept-article
uid: host-and-deploy/azure-iis-errors-reference
---
@@ -14,25 +15,25 @@ uid: host-and-deploy/azure-iis-errors-reference
:::moniker range=">= aspnetcore-6.0"
-This topic describes the most common errors and provides troubleshooting advice when hosting ASP.NET Core apps on Azure Apps Service and IIS.
+This article describes the most common errors and provides troubleshooting advice when hosting ASP.NET Core apps on Azure Apps Service and IIS.
See information on common app startup errors and instructions on how to diagnose errors.
Collect the following information:
* Browser behavior such as status code and error message.
-* Application Event Log entries
+* Application Event Log entries.
* Azure App Service: See .
* IIS
1. Select **Start** on the **Windows** menu, type *Event Viewer*, and press **Enter**.
1. After the **Event Viewer** opens, expand **Windows Logs** > **Application** in the sidebar.
-* ASP.NET Core Module stdout and debug log entries
+* ASP.NET Core Module stdout and debug log entries.
* Azure App Service: See .
- * IIS: Follow the instructions in the [Log creation and redirection](xref:host-and-deploy/aspnet-core-module#log-creation-and-redirection) and [Enhanced diagnostic logs](xref:host-and-deploy/iis/logging-and-diagnostics#enhanced-diagnostic-logs) sections of the ASP.NET Core Module topic.
+ * IIS: Follow the instructions in the [Log creation and redirection](xref:host-and-deploy/aspnet-core-module#log-creation-and-redirection) and [Enhanced diagnostic logs](xref:host-and-deploy/iis/logging-and-diagnostics#enhanced-diagnostic-logs) sections of the ASP.NET Core Module article.
Compare error information to the following common errors. If a match is found, follow the troubleshooting advice.
-The list of errors in this topic isn't exhaustive. If you encounter an error not listed here, open a new issue using the **Content feedback** button at the bottom of this topic with detailed instructions on how to reproduce the error.
+The list of errors in this article isn't exhaustive. If you encounter an error not listed here, open a new issue using the **Content feedback** button at the bottom of this article with detailed instructions on how to reproduce the error.
[!INCLUDE[Azure App Service Preview Notice](~/includes/azure-apps-preview-notice.md)]
@@ -293,7 +294,7 @@ Troubleshooting:
The process failed to start, most likely due to an app configuration or programming issue.
-For more information, see the following topics:
+For more information, see the following articles:
*
*
diff --git a/aspnetcore/host-and-deploy/iis/advanced.md b/aspnetcore/host-and-deploy/iis/advanced.md
index f060d199a7fb..f269eb54dd29 100644
--- a/aspnetcore/host-and-deploy/iis/advanced.md
+++ b/aspnetcore/host-and-deploy/iis/advanced.md
@@ -5,7 +5,8 @@ description: Advanced configuration with the ASP.NET Core Module and Internet In
monikerRange: '>= aspnetcore-5.0'
ms.author: tdykstra
ms.custom: mvc, sfi-image-nochange
-ms.date: 03/07/2025
+ms.date: 04/21/2026
+ms.topic: concept-article
uid: host-and-deploy/iis/advanced
---
# Advanced configuration of the ASP.NET Core Module and IIS
@@ -34,7 +35,7 @@ Configure the managed stack size using the `stackSize` setting in hexadecimal by
## Disallow rotation on config
-The `disallowRotationOnConfigChange` setting is intended for blue/green scenarios where a change to global config should not cause all sites to recycle. When this flag is true, only changes relevant to the site itself will cause it to recycle. For example, a site recycles if its *web.config* changes or something changes that is relevant to the site's path from IIS's perspective. But a general change to *applicationHost.config* would not cause an app to recycle. The following example sets this setting to true:
+The `disallowRotationOnConfigChange` setting is intended for blue/green scenarios where a change to global config shouldn't cause all sites to recycle. When this flag is true, only changes relevant to the site itself will cause it to recycle. For example, a site recycles if its *web.config* changes or something changes that's relevant to the site's path from IIS's perspective. But a general change to *applicationHost.config* wouldn't cause an app to recycle. The following example sets this setting to true:
```xml
```
-This setting corresponds to the API
+This setting corresponds to the API.
## Reduce 503 likelihood during app recycle
-By default, there is a one second delay between when IIS is notified of a recycle or shutdown and when ANCM tells the managed server to initiate shutdown. The delay is configurable via the `ANCM_shutdownDelay` environment variable or by setting the `shutdownDelay` handler setting. Both values are in milliseconds. The delay is primarily to reduce the likelihood of a race where:
+By default, there's a one-second delay between when IIS is notified of a recycle or shutdown and when ANCM tells the managed server to initiate shutdown. The delay is configurable via the `ANCM_shutdownDelay` environment variable or by setting the `shutdownDelay` handler setting. Both values are in milliseconds. The delay is primarily to reduce the likelihood of a race where:
* IIS hasn't started queuing requests to go to the new app.
* ANCM starts rejecting new requests that come into the old app.
@@ -104,9 +105,9 @@ The [ASP.NET Core Data Protection stack](xref:security/data-protection/introduct
If the Data Protection key ring is stored in memory when the app restarts:
-* All cookie-based authentication tokens are invalidated.
-* Users are required to sign in again on their next request.
-* Any data protected with the key ring can no longer be decrypted. This may include [CSRF tokens](xref:security/anti-request-forgery#aspnet-core-antiforgery-configuration) and [ASP.NET Core MVC TempData cookies](xref:fundamentals/app-state#tempdata).
+* All cookie-based authentication tokens are invalidated.
+* Users are required to sign in again on their next request.
+* Any data protected with the key ring can no longer be decrypted. This might include [CSRF tokens](xref:security/anti-request-forgery#aspnet-core-antiforgery-configuration) and [ASP.NET Core MVC TempData cookies](xref:fundamentals/app-state#tempdata).
To configure data protection under IIS to persist the key ring, use **one** of the following approaches:
@@ -144,7 +145,7 @@ To configure data protection under IIS to persist the key ring, use **one** of t
## IIS configuration
-**Windows Server operating systems**
+### Windows Server operating systems
Enable the **Web Server (IIS)** server role and establish role services.
@@ -164,7 +165,7 @@ Enable the **Web Server (IIS)** server role and establish role services.
1. Proceed through the **Confirmation** step to install the web server role and services. A server/IIS restart isn't required after installing the **Web Server (IIS)** role.
-**Windows desktop operating systems**
+### Windows desktop operating systems
Enable the **IIS Management Console** and **World Wide Web Services**.
@@ -196,7 +197,7 @@ Enable the **IIS Management Console** and **World Wide Web Services**.
An ASP.NET Core app can be hosted as an [IIS sub-application (sub-app)](/iis/get-started/planning-your-iis-architecture/understanding-sites-applications-and-virtual-directories-on-iis#applications). The sub-app's path becomes part of the root app's URL.
-Static asset links within the sub-app should use tilde-slash (`~/`) notation in MVC and Razor Pages. Tilde-slash notation triggers a [Tag Helper](xref:mvc/views/tag-helpers/intro) to prepend the sub-app's pathbase to the rendered relative link. For a sub-app at `/subapp_path`, an image linked with `src="~/image.png"` is rendered as `src="/subapp_path/image.png"`. The root app's Static File Middleware doesn't process the static file request. The request is processed by the sub-app's Static File Middleware.
+Static asset links within the sub-app should use tilde-slash (`~/`) notation in MVC and Razor Pages. Tilde-slash notation triggers a [Tag Helper](xref:mvc/views/tag-helpers/intro) to prepend the sub-app's pathbase to the rendered relative link. For a sub-app at `/subapp_path`, an image linked with `src="~/image.png"` is rendered as `src="/subapp_path/image.png"`. The root app's Static File Middleware doesn't process the static file request. The sub-app's Static File Middleware processes the request.
> [!NOTE]
> Razor components (`.razor`) shouldn't use tilde-slash notation. For more information, see .
@@ -219,10 +220,10 @@ For more information on the in-process hosting model and configuring the ASP.NET
## Application Pools
-App pool isolation is determined by the hosting model:
+The hosting model determines app pool isolation:
-* In-process hosting: Apps are required to run in separate app pools.
-* Out-of-process hosting: We recommend isolating the apps from each other by running each app in its own app pool.
+* **In-process hosting**: Apps are required to run in separate app pools.
+* **Out-of-process hosting**: We recommend isolating the apps from each other by running each app in its own app pool.
The IIS **Add Website** dialog defaults to a single app pool per app. When a **Site name** is provided, the text is automatically transferred to the **Application pool** textbox. A new app pool is created using the site name when the site is added.
@@ -240,7 +241,7 @@ If the IIS worker process requires elevated access to the app, modify the Access
1. Right-click on the directory and select **Properties**.
-1. Under the **Security** tab, select the **Edit** button and then the **Add** button.
+1. Under the **Security** tab, select the **Edit** button, and then the **Add** button.
1. Select the **Locations** button and make sure the system is selected.
@@ -260,19 +261,19 @@ Access can also be granted at a command prompt using the **ICACLS** tool. Using
ICACLS C:\sites\MyWebApp /grant "IIS AppPool\DefaultAppPool:(OI)(CI)RX"
```
-For more information, see the [icacls](/windows-server/administration/windows-commands/icacls) topic.
+For more information, see the [icacls](/windows-server/administration/windows-commands/icacls) article.
## HTTP/2 support
[HTTP/2](https://httpwg.org/specs/rfc7540.html) is supported with ASP.NET Core in the following IIS deployment scenarios:
* In-process
- * Windows Server 2016/Windows 10 or later; IIS 10 or later
- * TLS 1.2 or later connection
+ * Windows Server 2016/Windows 10 or later; IIS 10 or later.
+ * TLS 1.2 or later connection.
* Out-of-process
- * Windows Server 2016/Windows 10 or later; IIS 10 or later
+ * Windows Server 2016/Windows 10 or later; IIS 10 or later.
* Public-facing edge server connections use HTTP/2, but the reverse proxy connection to the [Kestrel server](xref:fundamentals/servers/kestrel) uses HTTP/1.1.
- * TLS 1.2 or later connection
+ * TLS 1.2 or later connection.
For an in-process deployment when an HTTP/2 connection is established, [`HttpRequest.Protocol`](xref:Microsoft.AspNetCore.Http.HttpRequest.Protocol*) reports `HTTP/2`. For an out-of-process deployment when an HTTP/2 connection is established, [`HttpRequest.Protocol`](xref:Microsoft.AspNetCore.Http.HttpRequest.Protocol*) reports `HTTP/1.1`.
@@ -290,8 +291,8 @@ For an ASP.NET Core app that targets the .NET Framework, OPTIONS requests aren't
When hosted in IIS by the ASP.NET Core Module version 2:
-* [Application Initialization Module](#application-initialization-module): App's hosted [in-process](xref:host-and-deploy/iis/in-process-hosting) or [out-of-process](xref:host-and-deploy/iis/out-of-process-hosting) can be configured to start automatically on a worker process restart or server restart.
-* [Idle Timeout](#idle-timeout): App's hosted [in-process](xref:host-and-deploy/iis/in-process-hosting) can be configured not to time out during periods of inactivity.
+* [**Application Initialization Module**](#application-initialization-module): App's hosted [in-process](xref:host-and-deploy/iis/in-process-hosting) or [out-of-process](xref:host-and-deploy/iis/out-of-process-hosting) can be configured to start automatically on a worker process restart or server restart.
+* [**Idle Timeout**](#idle-timeout): App's hosted [in-process](xref:host-and-deploy/iis/in-process-hosting) can be configured not to time out during periods of inactivity.
### Application Initialization Module
@@ -356,8 +357,8 @@ To prevent apps hosted [out-of-process](xref:host-and-deploy/iis/out-of-process-
### Application Initialization Module and Idle Timeout additional resources
* [IIS 8.0 Application Initialization](/iis/get-started/whats-new-in-iis-8/iis-80-application-initialization)
-* [Application Initialization ``](/iis/configuration/system.webserver/applicationinitialization/).
-* [Process Model Settings for an Application Pool ``](/iis/configuration/system.applicationhost/applicationpools/add/processmodel).
+* [Application Initialization ``](/iis/configuration/system.webserver/applicationinitialization/)
+* [Process Model Settings for an Application Pool ``](/iis/configuration/system.applicationhost/applicationpools/add/processmodel)
## Module, schema, and configuration file locations
@@ -385,13 +386,13 @@ To prevent apps hosted [out-of-process](xref:host-and-deploy/iis/out-of-process-
### Schema
-**IIS**
+**IIS**:
* `%windir%\System32\inetsrv\config\schema\aspnetcore_schema.xml`
* `%windir%\System32\inetsrv\config\schema\aspnetcore_schema_v2.xml`
-**IIS Express**
+**IIS Express**:
* `%ProgramFiles%\IIS Express\config\schema\aspnetcore_schema.xml`
@@ -399,11 +400,11 @@ To prevent apps hosted [out-of-process](xref:host-and-deploy/iis/out-of-process-
### Configuration
-**IIS**
+**IIS**:
* `%windir%\System32\inetsrv\config\applicationHost.config`
-**IIS Express**
+**IIS Express**:
* Visual Studio: `{APPLICATION ROOT}\.vs\config\applicationHost.config`
@@ -430,7 +431,7 @@ When deploying apps to servers with [Web Deploy](/iis/install/installing-publish
1. Under the server's node, select **Application Pools**.
-1. Right-click the site's app pool and select **Basic Settings** from the contextual menu.
+1. Right-click the site's app pool, and select **Basic Settings** from the contextual menu.
1. In the **Edit Application Pool** window, set the **.NET CLR version** to **No Managed Code**:
@@ -438,9 +439,9 @@ When deploying apps to servers with [Web Deploy](/iis/install/installing-publish
ASP.NET Core runs in a separate process and manages the runtime. ASP.NET Core doesn't rely on loading the desktop CLR (.NET CLR). The Core Common Language Runtime (CoreCLR) for .NET is booted to host the app in the worker process. Setting the **.NET CLR version** to **No Managed Code** is optional but recommended.
- * For a 32-bit (x86) [self-contained deployment](/dotnet/core/deploying/#self-contained-deployments-scd) published with a 32-bit SDK that uses the in-process hosting model, enable the Application Pool for 32-bit. In IIS Manager, navigate to **Application Pools** in the **Connections** sidebar. Select the app's Application Pool. In the **Actions** sidebar, select **Advanced Settings**. Set **Enable 32-Bit Applications** to `True`.
+ * For a 32-bit (x86) [self-contained deployment](/dotnet/core/deploying/#self-contained-deployments-scd) published with a 32-bit SDK that uses the in-process hosting model, enable the Application Pool for 32-bit. In IIS Manager, navigate to **Application Pools** in the **Connections** sidebar. Select the app's Application Pool. In the **Actions** sidebar, select **Advanced Settings**. Set **Enable 32-Bit Applications** to `True`.
- * For a 64-bit (x64) [self-contained deployment](/dotnet/core/deploying/#self-contained-deployments-scd) that uses the in-process hosting model, disable the app pool for 32-bit (x86) processes. In IIS Manager, navigate to **Application Pools** in the **Connections** sidebar. Select the app's Application Pool. In the **Actions** sidebar, select **Advanced Settings**. Set **Enable 32-Bit Applications** to `False`.
+ * For a 64-bit (x64) [self-contained deployment](/dotnet/core/deploying/#self-contained-deployments-scd) that uses the in-process hosting model, disable the app pool for 32-bit (x86) processes. In IIS Manager, navigate to **Application Pools** in the **Connections** sidebar. Select the app's Application Pool. In the **Actions** sidebar, select **Advanced Settings**. Set **Enable 32-Bit Applications** to `False`.
1. Confirm the process model identity has the proper permissions.
@@ -457,9 +458,9 @@ Shadow copying app assemblies to the [ASP.NET Core Module (ANCM)](xref:host-and-
When an ASP.NET Core app is running on Windows, the binaries are locked so that they can't be modified or replaced. Shadow copying enables the app assemblies to be updated while the app is running by making a copy of the assemblies.
-Shadow copy isn't intended to enable zero-downtime deployment, so its expected that IIS will still recycle the app, and some requests may get an [503 Service Unavailable](https://developer.mozilla.org/docs/Web/HTTP/Status/503) response. We recommend using a pattern like [blue-green deployments](https://www.martinfowler.com/bliki/BlueGreenDeployment.html) or [Azure deployment slots](/azure/app-service/deploy-best-practices#use-deployment-slots) for zero-downtime deployments. Shadow copy helps minimize downtime on deployments, but can't completely eliminate it.
+Shadow copy isn't intended to enable zero-downtime deployment, so it's expected that IIS will still recycle the app, and some requests might get a [503 Service Unavailable](https://developer.mozilla.org/docs/Web/HTTP/Reference/Status/503) response. We recommend using a pattern like [blue-green deployments](https://www.martinfowler.com/bliki/BlueGreenDeployment.html) or [Azure deployment slots](/azure/app-service/deploy-best-practices#use-deployment-slots) for zero-downtime deployments. Shadow copy helps minimize downtime on deployments, but it can't completely eliminate it.
-Shadow copying is enabled by customizing the ANCM handler settings in `web.config`:
+Customizing the ANCM handler settings in `web.config` enables shadow copying:
```