Fix it now
The content is on disk and IIS has nothing configured that is allowed to send it. Microsoft publishes 403.14 as directory listing denied, 404.3 as a MIME type restriction and 404.4 as no handler configured. None of the three means the file is missing.
%windir%\system32\inetsrv\appcmd list config "Default Web Site/" /section:handlers
%windir%\system32\inetsrv\appcmd list config "Default Web Site/" /section:staticContent
%windir%\system32\inetsrv\appcmd list config "Default Web Site/" /section:defaultDocument
- For 404.3, add the missing MIME mapping: IIS Manager, select the site, open MIME Types, choose Add, and enter the extension with its leading dot and the correct content type.
- For 403.14, add the default document that matches a file which actually exists in the folder, rather than switching directory browsing on.
- For 404.4, open Handler Mappings on the site and confirm a mapping exists for the path and verb being requested.
- If nothing static is served at all, the static content role service is probably not installed. Read the exact feature name off
Get-WindowsFeature Web-*and install that one, rather than copying a name out of an article. - For an application root returning 403.14, install the role service or module for the framework the application uses, then run
iisreset.
Directory browsing makes a 403.14 disappear by publishing a full listing of the folder to anyone who can reach the URL. Enable it only on a folder you have deliberately decided to make public.
If the content is served, you are done. If it is not, the next section explains how a request finds something willing to handle it, and where in that chain yours is falling through.
Why it happens
IIS matches every request against its handler mappings before anything reads the disk. A mapping ties a path or extension and a verb to a module. If a mapping matches, that module owns the request. If none matches, there is nothing to run, and 404.4 is published as exactly that: no handler configured. It is a configuration answer, not a file system one.
Static files are served by a module that will only send file types it has a MIME mapping for. That is deliberate. It stops the server handing out configuration files, databases and source that happen to sit in the web root. When you request an extension with no mapping, Microsoft publishes the result as a MIME type restriction, 404.3, and the fix is to add the one mapping rather than to loosen anything.
403.14, published as directory listing denied, comes last in that chain. The request resolved to a directory, the default document module worked through its list and matched none of them, and the directory listing module was asked to render the folder instead. Directory browsing is off by default, so it refuses. The common real cause is not a missing index file at all: it is an application whose handler was never registered, so requests that should have gone to the application fall through to plain directory handling.
500.37 belongs in the same conversation for a different reason. It is the ASP.NET Core Module reporting that the application did not start inside its startup time limit, which defaults to 120 seconds. A slow-starting application on a cold pool can look like a serving problem to somebody watching a browser, and it is not one.
The static content role service was never installed
You have this one if Every static file returns 404.3 on a freshly built server, while dynamic pages may work fine.
- List what is present and read the exact feature name from the output:
Get-WindowsFeature Web-* - Install the static content feature by the name that output gives you, and the default document feature at the same time if folder requests are also failing.
- Retry the request. These role services do not need a restart.
- Confirm with
appcmd list config "<site>/" /section:staticContentthat mappings now exist.
A minimal IIS install is a reasonable starting point for a locked-down server, but it will not serve a single static file until this feature is added.
One file extension has no MIME mapping
You have this one if One file type fails with 404.3 while everything else on the same site is served normally.
- In IIS Manager select the site and open MIME Types.
- Choose Add, enter the extension with its leading dot, and give it the correct content type.
- Add it at site level rather than server level unless every site genuinely needs it.
- Retry. The change applies immediately.
Map the correct content type rather than a generic one. Browsers treat fonts, scripts and media differently depending on what they are told they are.
The application’s handler was never registered
You have this one if 403.14 on the root of an application that clearly has code in it, and Handler Mappings shows nothing for its file type.
- Install the role service for the framework the application uses, rather than editing the handler list by hand.
- For ASP.NET Core, install the .NET Hosting Bundle, which registers the module and its handler.
- Run
iisresetafter adding a native module, then request the root URL again. - Confirm with
appcmd list config "<site>/" /section:handlersthat the mapping is now present.
Adding a default document makes the 403.14 go away without fixing anything. Register the handler.
The configuration points at a module that will not load
You have this one if A 500.19 carrying 0x8007007e or 0x800700c1 alongside the 404s, or a site that will not start at all.
- Read the HRESULT. 0x8007007e is published as an invalid or non-existent module or DLL reference; 0x800700c1 is a module whose bitness differs from the application pool, or a corrupted module.
- If the module belongs to software that has been uninstalled, remove its entry from the modules list in IIS Manager or from applicationHost.config.
- If it belongs to something you still use, repair or reinstall that product so the DLL and its dependencies are back.
- Enable Failed Request Tracing if the error does not name the reference; Microsoft documents it as the way to identify which one is wrong.
- Restart IIS and confirm the worker process starts and stays running.
Full reference
Matching what you see to what is missing
| What you see | What is actually missing |
|---|---|
| 403.14 on an application root | The application’s handler is not registered, so the request fell through to directory handling |
| 403.14 on a genuine content folder | No default document in the list matches a file that exists there |
| 404.3 on every static file | The static content role service is not installed |
| 404.3 on one extension only | That extension has no MIME mapping |
| 404.4 | No handler mapping matched the requested path and verb |
| 500.37 | The application did not finish starting inside the limit, 120 seconds by default |
| 500.19 with 0x8007007e or 0x800700c1 | A module reference is invalid, or a module’s bitness does not match the pool |
Reading the three sections that decide this
| Command | What it shows |
|---|---|
appcmd list config "<site>/" /section:handlers |
Every handler mapping in effect, in order |
appcmd list config "<site>/" /section:staticContent |
The MIME map the static file handler is working from |
appcmd list config "<site>/" /section:defaultDocument |
The default document list and its order |
appcmd list config "<site>/" /section:directoryBrowse |
Whether directory browsing is on, which it should not be |
appcmd search config "<site>/" /section:<name> |
Every level that sets one of these, which is how you find the one you did not expect |
Run these from %windir%\system32\inetsrv, or call appcmd by its full path. The effective configuration is the merge of every level above the one you ask about, so a mapping you cannot find in the site’s own web.config may be arriving from applicationHost.config.
MIME types, and where to stop
- Add the specific type for content you intend to publish. That is what the mapping is for.
- Do not configure the server to serve any unlisted extension. The restriction exists to stop the web root handing out whatever ends up in it.
- Add at site level unless every site on the box needs it. A long server-wide list is checked on every request and makes behaviour harder to reason about.
- Use the correct content type, not a generic one you know will work. Fonts, scripts and media are handled differently by browsers depending on the type they are given.
Default documents, and the trap in them
A default document list is checked in order on every folder request, and the first entry that matches a file present in the folder wins. That has two consequences worth knowing. A long list at server level costs something on every request. And adding a default document to an application root, to silence a 403.14, produces a site that appears to work while the framework’s handler is still not registered, so anything with a route rather than a file behind it keeps failing.
Directory browsing publishes a full listing of the folder to anyone who can reach the URL, including files you never intended to expose. It makes a 403.14 disappear and it is almost never the right fix. Turn it on only where you have deliberately decided the folder should be public.
Two event IDs you will see quoted for this, and what to do with them
Event ID 2276 and Event ID 2280 turn up in the System log on servers with module problems, and they are widely quoted as meaning a module DLL failed to load. Microsoft does not publish a meaning for either of them, so this article will not tell you one. Read the entries on the machine: they are written by the IIS worker process source and they carry the detail themselves. Then diagnose from the 500.19 HRESULTs above, which are published and which cover the same fault properly.
When the mapping is right and it still will not serve
- Confirm the request is reaching the site you think it is. Host headers and bindings send requests to a different site more often than anyone expects.
- Check the IIS log for the request and read sc-status and sc-substatus together, so you are diagnosing the sub-status you actually have.
- Check request filtering. A request rejected by filtering is not a handler problem and produces a different sub-status.
- Confirm the file is where the physical path says it is, and that the pool identity can read it. A permission failure on the folder produces a 401.3, not a 404.
Every code this article covers
| Code | What it points at | Source |
|---|---|---|
HTTP 403.14 |
Directory listing denied: the request resolved to a directory, no default document matched, and listing the directory is not permitted | Microsoft Learn |
HTTP 404.3 |
MIME type restriction: the static file handler has no MIME mapping for the requested file type | Microsoft Learn |
HTTP 404.4 |
No handler configured: no handler mapping matched the requested path and verb | Microsoft Learn |
HTTP 500.37 |
ANCM Failed to Start Within Startup Time Limit: the application did not start inside the limit, which defaults to 120 seconds | Microsoft Learn |
Event ID 2276 |
Seen in the System log from the IIS worker process source on servers with module problems. Read the entry itself and diagnose from the published 500.19 HRESULTs instead | not published by the vendor |
Event ID 2280 |
The same: written by the IIS worker process source, with no published meaning. Treat it as a pointer to the module list rather than as a diagnosis | not published by the vendor |
Confirm the fix worked
- Request the previously failing URL and confirm the expected content is returned.
- Request a file of the same type from a different folder, to confirm the mapping applies where you intended.
- Run
appcmd list config "<site>/" /section:handlersand confirm the mapping you added is in the merged result. - Check the IIS log for the request and confirm sc-status 200 with sc-substatus 0.
- Confirm directory browsing is still disabled on every folder where you did not deliberately enable it.
Questions people ask about this
Does any of this need a purchase?
No. Every fix here is a role service already part of Windows Server, or a setting in IIS Manager. There is nothing to buy and no licence that changes the outcome.
Why does my MVC application return 403.14 when it has no index page?
Because without a registered handler, IIS treats the request as a plain folder request, finds no default document, and refuses to list the directory. Adding a default document hides it. Registering the framework’s handler fixes it.
Is adding a MIME type a security risk?
Adding one specific type for content you intend to publish is fine. Configuring the server to serve any unlisted extension is not, because the restriction is what stops the web root handing out whatever lands in it.
Should I add default documents at server level or site level?
Site level, unless every site on the box uses the same file name. The list is checked in order on every folder request, and a long server-wide one makes behaviour harder to reason about.
What do Event IDs 2276 and 2280 mean?
Microsoft does not publish a meaning for either, so nobody should be telling you one with confidence. Read the entries on the server, then diagnose the same fault through the published route: the 500.19 HRESULTs 0x8007007e for an invalid module reference and 0x800700c1 for a bitness mismatch.
