HTTP 503 Service Unavailable — the application pool has stopped
IIS is running but the pool that should serve the site is stopped, so http.sys answers 503 itself without ever reaching the application.
What you see
Every request to a site returns a bare 503 page. IIS Manager shows the application pool as Stopped, and starting it stops again after the next request.
What is actually wrong
Rapid-fail protection stopped the pool after repeated worker crashes, the pool identity's password has expired, or the worker cannot load .NET.
Codes and articles
Fixes (2)
Fix the pool identity
The pool will not start. An expired or changed service-account password is the usual reason.
Read the events — 5021 is a bad identity password, 5057 a .NET load failure.
Get-WinEvent -LogName System -MaxEvents 40 | Where-Object { $_.ProviderName -like '*WAS*' -or $_.ProviderName -like '*IIS*' } | Format-List TimeCreated, Id, MessageCheck what identity the pool runs as.
Import-Module WebAdministrationGet-ChildItem IIS:\AppPools | ForEach-Object { [PSCustomObject]@{ Pool=$_.Name; State=$_.State; Identity=$_.processModel.identityType; User=$_.processModel.userName } } | Format-Table -AutoSize
Re-enter the password for a custom identity.
Set-ItemProperty 'IIS:\AppPools\MyPool' -Name processModel.password -Value 'ThePassword'Better, move it to a group Managed Service Account so the password is never a problem again.
Set-ItemProperty 'IIS:\AppPools\MyPool' -Name processModel.identityType -Value SpecificUserSet-ItemProperty 'IIS:\AppPools\MyPool' -Name processModel.userName -Value 'EXAMPLE\svc_web$'Set-ItemProperty 'IIS:\AppPools\MyPool' -Name processModel.password -Value ''
A gMSA's password is rotated by AD and never typed anywhere, which removes the annual outage this fault represents.
Start the pool.
Start-WebAppPool -Name MyPool
Get-ChildItem IIS:\AppPools | Format-Table Name, State -AutoSizeInvoke-WebRequest http://localhost/ -UseBasicParsing | Select-Object StatusCode
Stop the worker crashing and clear rapid-fail protection
The pool starts then stops. Something is killing the worker process and IIS is refusing to keep restarting it.
Find the crash. Event 5002 is rapid-fail protection tripping; the Application log has the actual exception.
Get-WinEvent -LogName Application -MaxEvents 30 | Where-Object { $_.Id -in 1000,1026 } | Format-List TimeCreated, Id, MessageRead the rapid-fail settings — five failures in five minutes is the default and is easily hit.
Get-ItemProperty 'IIS:\AppPools\MyPool' -Name failure | Format-List rapidFailProtection, rapidFailProtectionInterval, rapidFailProtectionMaxCrashesStart the pool and watch whether it survives.
Start-WebAppPool -Name MyPoolStart-Sleep 20Get-ChildItem IIS:\AppPools | Where-Object Name -eq MyPool | Format-Table Name, State
Fix the underlying crash. If it is a .NET version mismatch, confirm the runtime the pool is set to matches the application.
Get-ItemProperty 'IIS:\AppPools\MyPool' -Name managedRuntimeVersion, enable32BitAppOnWin64 | Format-ListOnly widen rapid-fail protection once the crash is understood — never as the fix itself.
Set-ItemProperty 'IIS:\AppPools\MyPool' -Name failure.rapidFailProtectionMaxCrashes -Value 20Rapid-fail protection exists to stop a broken application consuming the server. Raising the limit hides the crash and leaves the server restarting a failing worker twenty times instead of five.
Get-WinEvent -LogName System -MaxEvents 20 | Where-Object Id -eq 5002Related faults
Where this stops. This write-up was written and checked by hand. It says what each step changes, how to confirm it worked and how to reverse it, and anything destructive is flagged before you reach it. If it does not match what your machine is doing, search the Support Centre for the exact code or message — and when something needs a person, get in touch.