Skip to content
ohsudo, Home
Windows

IIS "HTTP Error 500.19" and "503 Service Unavailable": read the code, then fix web.config or the app pool

Fix IIS "HTTP Error 500.19" by its error code (a missing module, a bad web.config, permissions) and "503 Service Unavailable" by finding why the app pool stopped.

Intermediate4 min readApplies to IIS 10 · Windows Server 2016+ · Windows 10 · Windows 11 · ASP.NET · ASP.NET Core

by OhSudo ··

Checked on real software: IIS, Windows Server · November 2026How we check

Not sure this is your cause?Find it step by step: Website down →

Two of the most common IIS failures, and neither has anything to do with your code running:

HTTP Error 500.19 - Internal Server Error
The requested page cannot be accessed because the related configuration data for the page is invalid.
Error Code 0x8007000d
HTTP Error 503. The service is unavailable.

500.19 means IIS can’t read or understand your configuration, so it stops before starting your application. 503 means the application pool that should answer isn’t running. Each has one place to look first.

  1. Requestto the site
  2. IIS reads web.configinvalid: 500.19
  3. Application poolstopped: 503(breaks here)
Neither error comes from your code. 500.19: IIS can't read the configuration, so it stops before the app. 503: the application pool that should answer isn't running.

TL;DR

For 500.19, read the Error Code on the page, which you only see in full from the server itself:

Terminal window
Invoke-WebRequest http://localhost/ -UseBasicParsing

For 503, check the pool, then why it stopped:

Terminal window
Import-Module WebAdministration
Get-ChildItem IIS:\AppPools | Select-Object Name, State
Get-WinEvent -LogName System -MaxEvents 30 | Where-Object ProviderName -like '*WAS*'

500.19: see the details

Browsers on other machines get a generic page. Open the site on the server, as http://localhost/, to get the full one. It shows the error code, the config file, and often the exact line.

Error code Means Usual fix
0x8007000d A section IIS doesn’t recognize, usually a missing module Install the module (below)
0x80070005 Access denied to a config file or folder Give IIS read rights (below)
0x8007007e A global module’s DLL is missing Repair or reinstall that module
0x80070021 A section is locked at a higher level Unlock it (below)
0x800700b7 A duplicate entry Add <clear /> or <remove> in that section, or delete the duplicate

0x8007000d: a missing module

The classic: a site uses <rewrite> and the URL Rewrite module isn’t installed. For ASP.NET Core, it’s <aspNetCore>, which needs the .NET Hosting Bundle. Look at what your web.config uses:

<system.webServer>
<rewrite> ... </rewrite> <!-- URL Rewrite module -->
<aspNetCore processPath="dotnet" /> <!-- .NET Hosting Bundle -->
</system.webServer>

Check what’s installed:

Terminal window
Get-WebGlobalModule | Select-Object Name
Get-WindowsFeature Web-* | Where-Object Installed

Install what’s missing from Microsoft’s site, then restart IIS. The Hosting Bundle installer needs IIS to be installed first. If you installed it in the other order, run its repair.

Terminal window
iisreset

If it isn’t a module, then the XML itself is broken. A missing > also gives this code. Check it:

Terminal window
[xml](Get-Content C:\inetpub\wwwroot\web.config) | Out-Null

An error from that line points at the problem.

0x80070005: permissions

IIS reads config files as its own identities. A site copied from elsewhere may not allow them. Give read access to the site’s folder:

Terminal window
icacls C:\inetpub\mysite /grant "IIS_IUSRS:(OI)(CI)RX" /T
icacls C:\inetpub\mysite /grant "IUSR:(OI)(CI)RX" /T

Is the folder on a network share? Then the pool’s identity needs rights on the share too, and the virtual directory’s Connect as must use an account that has them.

0x80070021: a locked section

The server’s main config doesn’t let a site override this section. Unlock it, if your site really needs to:

Terminal window
& $env:windir\system32\inetsrv\appcmd.exe unlock config -section:system.webServer/handlers
& $env:windir\system32\inetsrv\appcmd.exe unlock config -section:system.webServer/modules

Often the message means an IIS feature is missing rather than locked, in which case the feature’s the fix. For example, ASP.NET applications need ASP.NET 4.8 in Windows features:

Terminal window
Install-WindowsFeature Web-Asp-Net45

503: is the pool running?

Terminal window
Import-Module WebAdministration
Get-ChildItem IIS:\AppPools | Select-Object Name, State
Start-WebAppPool -Name "DefaultAppPool"

If it was Stopped and starts, refresh a few times. A pool that stops again after a few requests is crashing, and IIS’s Rapid-Fail Protection has turned it off: by default, 5 failures within 5 minutes. Restarting won’t help until you find out why.

503: why it stopped

Terminal window
Get-WinEvent -LogName System -MaxEvents 50 |
Where-Object ProviderName -like '*WAS*' |
Format-List TimeCreated, Message
Get-WinEvent -LogName Application -MaxEvents 30 |
Where-Object LevelDisplayName -eq 'Error' |
Format-List TimeCreated, ProviderName, Message

The usual reasons:

  • The pool’s password has expired or changed. If it runs as a specific account, events 5021 or 5057 from WAS say so. Update the account in Advanced Settings → Identity.
  • The application crashes at start. The Application log has the exception. With ASP.NET Core, set stdoutLogEnabled="true" in web.config for a while to get its output.
  • 32-bit DLLs in a 64-bit pool, or the reverse. Check Enable 32-Bit Applications in the pool’s settings.
  • A module failing to load, which you can see in the System log, naming the DLL.

503 with the pool running

Then the request may not be reaching it. The site’s binding may be claimed by another registration in HTTP.sys, as a leftover from another tool:

Terminal window
netsh http show urlacl
netsh http show servicestate

Remove a reservation that doesn’t belong: netsh http delete urlacl url=http://+:80/. The queue might also be full, in which case the pool has hit its limit. Look at the request queue limit in its advanced settings, and at what’s making the application slow.

Warning

Turning off Rapid-Fail Protection hides the crash and keeps restarting a broken application. And for a production site, turn stdoutLogEnabled back off when you’re done, as that log isn’t rotated and it can fill up the disk.

Shell, we have a problem!

Similar, but different: 500.21 is a handler mismatch, often an ASP.NET application in the wrong pipeline mode. 500.30 and 502.5 are ASP.NET Core failing to start. 401.3 is NTFS permissions on the content. 404.3 means no handler for that file type. A Windows service that won’t start is error 1053. On the Linux side, see Nginx 502 and Nginx 504, which fail for similar reasons.

Found this useful? Share it.

Found a mistake? Let us know at contact@ohsudo.com.

Articles

Related articles