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:
- Clear the IIS configuration cache:
iisreset /noforce
- Test with
curl -v http://new.ianquigley.com/index.html
- 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:
- sc-win32-status: 2 in W3SVC logs
- 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"