I recently hit this error after moving an application from classic ASP.NET / .NET Framework hosting over to ASP.NET Core on IIS:
HTTP Error 500.30 – ASP.NET Core app failed to start
The page showed the usual Microsoft message:
Common solutions to this issue:
The app failed to start
The app started but then stopped
The app started but threw an exception during startup
Troubleshooting steps:
Check the system event log for error messages
Enable logging the application process’ stdout messages
Attach a debugger to the application process and inspect
That is all technically correct, but it can send you down a rabbit hole pretty quickly.
In my case, the fix was simple:
Application Pool > .NET CLR Version: No Managed Code
Application Pool > Managed pipeline mode: Integrated
That was it.
Because the site had previously been running as a classic ASP.NET application, the IIS Application Pool was still configured like an older .NET Framework app. ASP.NET Core is different. It does not run inside the old .NET Framework CLR in the same way, so the app pool should usually be set to No Managed Code.
The error
The browser showed:
HTTP Error 500.30 – ASP.NET Core app failed to start
This usually means IIS has reached the ASP.NET Core hosting module, but the actual application failed during startup.
In plain English:
IIS is alive.
The site is being reached.
But the ASP.NET Core app did not successfully start.
First thing to check: the Application Pool
Open IIS Manager.
Go to:
Application Pools
Find the app pool used by your site.
Right-click it and choose:
Basic Settings
For an ASP.NET Core app, check:
.NET CLR Version: No Managed Code
Managed pipeline mode: Integrated
This can feel wrong if you are used to old ASP.NET MVC or Web Forms apps, where you might expect to select a .NET CLR version.
But for ASP.NET Core, No Managed Code is normally correct.
ASP.NET Core runs through the ASP.NET Core Module and the .NET runtime, not through the classic IIS-hosted .NET Framework pipeline.
Why this happens during an ASP.NET to ASP.NET Core migration
If you are replacing an older ASP.NET Framework application with a newer ASP.NET Core version, IIS may still have settings left over from the old app.
For example, the previous app pool might have been configured as:
.NET CLR Version: v4.0
Managed pipeline mode: Integrated
That is common for older ASP.NET applications.
But once you deploy ASP.NET Core, you generally want:
.NET CLR Version: No Managed Code
Managed pipeline mode: Integrated
If you forget this, you may get a startup failure like:
HTTP Error 500.30 – ASP.NET Core app failed to start
Other simple things to check
After checking the app pool, I would check these next.
- Is the .NET Hosting Bundle installed?
On the IIS server, open PowerShell and run:
dotnet –list-runtimes
For a .NET 8 app, you should see something like:
Microsoft.AspNetCore.App 8.0.x
Microsoft.NETCore.App 8.0.x
If Microsoft.AspNetCore.App is missing, install the correct ASP.NET Core Hosting Bundle for your app version.
The hosting bundle is important because IIS needs the ASP.NET Core Module to launch the app.
- Is AspNetCoreModuleV2 available in IIS?
In IIS Manager, click the server name, then open:
Modules
Look for:
AspNetCoreModuleV2
If it is missing, the hosting bundle may not be installed properly.
- Does web.config point to the right DLL or EXE?
In the published site folder, open:
web.config
For a framework-dependent ASP.NET Core deployment, you may see something like:
Check that:
YourApp.dll exists
The file name is correct
The path is correct
web.config is in the site root
For a self-contained deployment, it may look more like:
Again, make sure the .exe actually exists.
- Try running the app manually
On the server, open PowerShell and go to the published site folder:
cd “C:\inetpub\wwwroot\YourApp”
Then run:
dotnet .\YourApp.dll
Or if it is self-contained:
.\YourApp.exe
If the app has a startup problem, this often prints the real error directly to the console.
You may see errors like:
Missing runtime
Invalid appsettings.json
Database login failed
Unable to resolve service for type…
File permission denied
Certificate or Key Vault issue
This is often much more useful than the browser error.
- Check Event Viewer
Open:
Event Viewer > Windows Logs > Application
Look for recent errors from:
IIS AspNetCore Module V2
.NET Runtime
Application Error
You can also use PowerShell:
Get-WinEvent -LogName Application -MaxEvents 100 |
Where-Object {
$_.ProviderName -like “AspNetCore” -or
$_.ProviderName -like “.NET Runtime” -or
$_.ProviderName -like “Application Error“
} |
Select-Object TimeCreated, ProviderName, Id, LevelDisplayName, Message |
Format-List
- Enable stdout logging temporarily
In web.config, change:
stdoutLogEnabled=”false”
to:
stdoutLogEnabled=”true”
Example:
Then create a logs folder in the site directory:
mkdir “C:\inetpub\wwwroot\YourApp\logs”
Give the app pool identity permission to write to it:
icacls “C:\inetpub\wwwroot\YourApp\logs” /grant “IIS AppPool\YourAppPoolName:(OI)(CI)M”
Recycle the app pool, browse to the site again, and then check the logs folder.
You may get a file like:
stdout_*.log
Important: turn stdout logging off again once you are finished.
stdoutLogEnabled=”false”
Otherwise the logs can grow and fill the disk.
- Check the environment name
ASP.NET Core commonly loads different settings depending on the environment.
For example:
appsettings.json
appsettings.Development.json
appsettings.UAT.json
appsettings.Production.json
The environment is controlled by:
ASPNETCORE_ENVIRONMENT
In IIS, you can set it in web.config:
If the server is accidentally running as Production when you expected UAT, the app may load the wrong connection string or missing settings.
- Check database permissions
Another common cause of 500.30 is a database failure during startup.
For example:
Cannot open database requested by the login.
Login failed for user…
This is especially common if the app works when you run it manually, but fails under IIS.
Why?
Because these may be different identities:
Manual test: DOMAIN\YourUser
IIS app: IIS AppPool\YourAppPoolName
or:
IIS app: DOMAIN\ServiceAccount
So the database might allow your personal login, but not the app pool or service account.
My simple checklist for HTTP Error 500.30
Start with the easy things:
- Check the App Pool
.NET CLR Version = No Managed Code
Managed pipeline mode = Integrated - Confirm the .NET Hosting Bundle is installed
- Confirm AspNetCoreModuleV2 exists in IIS
- Check web.config points to the correct DLL or EXE
- Run the app manually from PowerShell
- Check Event Viewer
- Enable stdout logging temporarily
- Check ASPNETCORE_ENVIRONMENT
- Check database / file / certificate permissions
Final note
The error message makes it sound like something deep inside the application has exploded, and sometimes that is true.
But if you have just moved from classic ASP.NET to ASP.NET Core, check the IIS Application Pool first.
In my case, this fixed it:
.NET CLR Version: No Managed Code
Managed pipeline mode: Integrated
Simple fix. Painful error.
Leave a Reply