Many IIS administrators encounter a frustrating scenario where URLs containing a single percent sign (like http://example.com/%
) trigger HTTP 400 Bad Request errors. While Microsoft's KB820129 suggests registry modifications, these solutions don't always work for this specific case.
The common approach of setting AllowRestrictedChars=1
and PercentUAllowed=1
in the registry (under HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\Services\HTTP\Parameters
) typically works for URLs containing %
followed by hex digits (like %20
), but fails for standalone percent signs.
Here are three effective approaches:
1. URL Rewrite Module Solution
Add this rule to your web.config:
<rule name="Fix Percent Sign" patternSyntax="ExactMatch">
<match url="%" />
<action type="Rewrite" url="/errorpages/percenterror.html" />
</rule>
2. Custom Error Page Configuration
Configure your web.config to handle 400 errors:
<httpErrors errorMode="Custom">
<remove statusCode="400" />
<error statusCode="400" path="/errorpages/badrequest.html" responseMode="ExecuteURL" />
</httpErrors>
3. Application Request Routing (ARR) Fix
For load-balanced environments, add this to ApplicationHost.config:
<system.webServer>
<proxy enabled="true" />
<rewrite>
<rules>
<rule name="ARR_percent_fix" stopProcessing="true">
<match url="^%$" />
<action type="Rewrite" url="/" />
</rule>
</rewrite>
</rewrite>
</system.webServer>
For persistent cases, create a DWORD (32-bit) value called PercentUEncoding
under HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\Services\HTTP\Parameters
and set it to 1. Then restart HTTP.SYS:
net stop http
net start http
After implementation, verify with PowerShell:
Invoke-WebRequest -Uri "http://yoursite.com/%" -UseBasicParsing
Or using curl:
curl -v http://yoursite.com/%
When working with IIS servers, you might encounter a frustrating scenario where URLs containing a standalone percentage sign (like http://yoursite.com/%) return a raw 400 Bad Request error instead of being handled gracefully. This differs from how other web servers like Apache or Nginx handle such requests.
While Microsoft's KB820129 suggests registry modifications like:
Windows Registry Editor Version 5.00
[HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\Services\HTTP\Parameters]
"AllowRestrictedChars"=dword:00000001
"PercentUAllowed"=dword:00000001
These often don't solve the /% case specifically. The issue stems from how IIS's URL validation pipeline processes malformed percent-encoded sequences at a fundamental level.
Here's what actually works in production environments:
1. URL Rewrite Module Configuration
<rewrite>
<rules>
<rule name="Catch percentage sign" patternSyntax="ECMAScript" stopProcessing="true">
<match url="^%$" />
<action type="CustomResponse" statusCode="400"
statusReason="Bad Request"
statusDescription="Invalid URL encoding" />
</rule>
</rules>
</rewrite>
2. Custom Error Page Setup
Configure your web.config to handle 400 errors elegantly:
<httpErrors errorMode="Custom">
<remove statusCode="400" />
<error statusCode="400"
path="/errors/400.html"
responseMode="ExecuteURL" />
</httpErrors>
3. HTTP.sys Deep Dive
For advanced cases, combine registry tweaks with URLScan (for older IIS) or Request Filtering:
<security>
<requestFiltering allowDoubleEscaping="true">
<denyUrlSequences>
<add sequence="%%" />
</denyUrlSequences>
</requestFiltering>
</security>
After implementation, verify with:
curl -I http://yoursite.com/%
telnet yoursite.com 80
GET /% HTTP/1.1
Host: yoursite.com
Remember that:
- Registry changes require HTTP.sys restart (net stop http / net start http)
- These modifications might affect security scanning tools
- Always test in staging first