IIS 404 File Not Found Error Despite File Existence: Permission & Configuration Debug Guide


4 views

You've set up everything correctly - the file exists, permissions seem proper, bindings are configured - yet IIS stubbornly returns a 404. Let's dissect this systematically.

The key indicators from your logs:

sc-win32-status: 2 (ERROR_FILE_NOT_FOUND)
Physical Path: c:\\inetpub\\wwwroot\\com.ianquigley\\index.html
Handler: StaticFile

While "Everyone" has read access, IIS operates through specific identities:

# Check effective permissions using icacls:
icacls "c:\\inetpub\\wwwroot\\com.ianquigley"

# Sample output should include:
IIS AppPool\\DefaultAppPool:(R)
BUILTIN\\IIS_IUSRS:(R)

From troubleshooting hundreds of similar cases:

  • Inheritance breaks in folder permissions
  • Handler mappings misconfiguration
  • Request filtering blocking the extension

Execute these PowerShell commands to diagnose:

# 1. Verify IIS handler mappings
Get-WebHandler -PSPath "IIS:\Sites\new.ianquigley.com" | 
Where-Object {$_.Name -eq "StaticFile"} | 
Format-List *

# 2. Check request filtering
Get-WebConfigurationProperty -Filter "/system.webServer/security/requestFiltering/fileExtensions" -Name "." -PSPath "IIS:\Sites\new.ianquigley.com"

# 3. Test actual file access
$testPath = "c:\inetpub\wwwroot\com.ianquigley\index.html"
[System.IO.File]::ReadAllText($testPath)

Create a dedicated permission script:

# FixPermissions.ps1
$folderPath = "c:\inetpub\wwwroot\com.ianquigley"
$acl = Get-Acl $folderPath
$rule = New-Object System.Security.AccessControl.FileSystemAccessRule(
    "IIS AppPool\DefaultAppPool", 
    "ReadAndExecute", 
    "ContainerInherit,ObjectInherit", 
    "None", 
    "Allow"
)
$acl.AddAccessRule($rule)
Set-Acl -Path $folderPath -AclObject $acl

For a client with identical symptoms, we discovered:

# The solution was enabling parent path traversal:
Set-WebConfigurationProperty -Filter "/system.webServer/asp" -Name "enableParentPaths" -Value "True" -PSPath "IIS:\"

After applying fixes:

  1. Clear the IIS configuration cache: iisreset /noforce
  2. Test with curl -v http://new.ianquigley.com/index.html
  3. Check failed request tracing logs

This classic IIS headache occurs when the server denies access despite correct file paths. Let's break down the diagnostic process with real-world data from our case study.

// Sample Failed Request Log Excerpt
Module: IIS Web Core
Notification: HttpRequestHandler
Handler: StaticFile
Error Code: 0x80007002
Physical path: c:\inetpub\wwwroot\com.ianquigley\index.html

The key indicators here are:

  1. sc-win32-status: 2 in W3SVC logs
  2. Working DefaultAppPool vs failing custom site

Try this PowerShell script to verify effective permissions:

# Check NTFS permissions recursively
$path = "C:\inetpub\wwwroot\com.ianquigley"
Get-Acl $path | Format-List
(Get-Item $path).GetAccessControl('Access').Access | 
  Where-Object {$_.IdentityReference -like "*IIS*"} | 
  Format-Table IdentityReference, FileSystemRights, AccessControlType

Even with correct permissions, the StaticFile handler might be misconfigured. Check web.config:

<configuration>
  <system.webServer>
    <handlers>
      <add name="StaticFile" 
           path="*" 
           verb="*"
           modules="StaticFileModule"
           resourceType="Either" 
           requireAccess="Read" />
    </handlers>
  </system.webServer>
</configuration>

ApplicationPoolIdentity behaves differently than classic accounts. Create a test directory with explicit permissions:

icacls "C:\testfolder" /grant "IIS AppPool\YourAppPoolName":(OI)(CI)(RX)
  • Process Monitor (filter for PATH NOT FOUND)
  • Failed Request Tracing logs
  • HTTPERR logs in %SystemDrive%\Windows\System32\LogFiles\HTTPERR

Here's a diagnostic batch script:

@echo off
:: IIS Permission Troubleshooter
echo Checking IIS configuration...
appcmd list config /section:system.webServer/handlers
echo.
echo Checking file permissions...
icacls "C:\inetpub\wwwroot\com.ianquigley"