When IIS throws the error "This configuration section cannot be used at this path" with error code 0x80070021, it typically indicates a configuration inheritance conflict. The authentication section in web.config is being blocked by higher-level configuration locks.
Beyond just checking applicationHost.config, we need to examine all possible configuration layers:
# PowerShell command to check locked sections
Get-WebConfigurationLock -Filter "system.webServer/security/authentication/*"
This helps identify exactly which authentication modules are locked at which levels.
Instead of manual editing, consider these programmatic approaches:
# Using appcmd to unlock specific sections
%windir%\system32\inetsrv\appcmd unlock config -section:system.webServer/security/authentication/anonymousAuthentication
%windir%\system32\inetsrv\appcmd unlock config -section:system.webServer/security/authentication/windowsAuthentication
# Alternative PowerShell method
Import-Module WebAdministration
Set-WebConfigurationProperty -Filter "system.webServer/security/authentication/anonymousAuthentication" -Name overrideMode -Value Allow -Location "Default Web Site"
To visualize the complete configuration hierarchy:
# Generate configuration report
& "$env:windir\system32\inetsrv\appcmd" list config /section:anonymousAuthentication /xml
This outputs all configuration sources affecting the authentication settings.
- Deployment conflicts: When web.config is deployed after applicationHost.config changes
- Feature dependencies: Windows Authentication feature must be installed
- Location tag issues: Verify path attributes match exactly
Example of proper location tag usage:
For persistent cases, enable failed request tracing:
# Enable tracing
Add-WebConfigurationProperty -PSPath IIS:\ -Filter "system.applicationHost/sites/siteDefaults/traceFailedRequestsLogging" -Name enabled -Value true
This generates detailed logs showing exactly which configuration level is denying access.
When IIS throws that dreaded 0x80070021 error indicating a locked configuration section, it often sends developers down a rabbit hole. The error message clearly points to authentication module conflicts, but sometimes the usual fixes don't work as expected.
IIS applies configuration settings through a hierarchical system. The locking can occur at multiple levels:
Machine-level (applicationHost.config)
↓
Site-level (web.config)
↓
Application-level (web.config)
↓
Virtual Directory-level (web.config)
When standard unlocking methods fail, try these deeper inspection approaches:
1. Configuration Tracing
Use AppCmd to trace configuration inheritance:
appcmd list config /section:system.webServer/security/authentication /commit:path
2. PowerShell Deep Inspection
This PowerShell script checks all potential lock locations:
Import-Module WebAdministration
Get-WebConfigurationProperty -Filter "system.webServer/security/authentication"
-Name * -Recurse -Location * |
Where {$_.IsLocked -eq $true} |
Format-List -Property PSPath,IsLocked
Many developers overlook the Feature Delegation settings in IIS Manager. Even if you've modified applicationHost.config, delegation settings might still override your changes.
Verification Steps:
- Open IIS Manager
- Select the server node (not your site)
- Open "Feature Delegation"
- Find "Authentication" sections
- Ensure they're set to "Read/Write"
For production environments, implement this comprehensive approach:
<location path="." inheritInChildApplications="false" overrideMode="Allow">
<system.webServer>
<security>
<authentication>
<anonymousAuthentication enabled="true" />
<windowsAuthentication enabled="false" />
</authentication>
</security>
</system.webServer>
</location>
- Mixing old (allowOverride) and new (overrideMode) locking syntax
- Not checking both 32-bit and 64-bit configuration files
- Overlooking parent path locks when using virtual directories
- Forgetting to restart IIS after configuration changes
When all else fails, enable failed request tracing to get detailed logs:
%windir%\system32\inetsrv\appcmd set config /section:httpLogging
/selectiveLogging:uriWithFailure /commit:apphost