When implementing URL rewriting in Apache using mod_rewrite, many developers encounter a puzzling behavior: URLs with parameter strings longer than 255 characters mysteriously fail with 403 Forbidden errors, while direct access to the same parameters works perfectly.
# Working case (short parameter)
http://example.com/1,2,3/foo/
# Failing case (long parameter)
http://example.com/1,2,3,...,256/foo/
This limitation stems from Apache's internal path handling before mod_rewrite even processes the request. The issue occurs because:
- Apache has a default PATH_MAX limit (typically 255-4096 bytes depending on OS)
- The check happens before mod_rewrite sees the request
- No rewrite logs are generated because the failure occurs in earlier processing
Here are three proven approaches to solve this:
1. Adjust LimitRequestLine and LimitRequestFieldSize
# In httpd.conf or virtual host configuration
LimitRequestLine 4094
LimitRequestFieldSize 4094
2. Alternative URL Structure
Consider passing the parameter via POST or splitting into multiple paths:
# Original problematic rule
RewriteRule ^([\d,]+)/foo/$ /foo.php?id=$1 [L,QSA]
# Alternative approach
RewriteRule ^foo/([\d,]+)/?$ /foo.php?id=$1 [L,QSA]
3. Client-Side Compression
For extremely long parameters, implement Base64 encoding in JavaScript:
// JavaScript encode
const params = [1,2,3,...,1000].join(',');
const compressed = btoa(params);
// Send as: example.com/foo/?q=[compressed]
// PHP decode
$compressed = $_GET['q'];
$params = base64_decode($compressed);
To verify your solution works with long parameters:
- Create a test script that generates parameter strings of varying lengths
- Monitor both access.log and error.log during testing
- Use curl with different parameter lengths for validation
# Test command
curl -I "http://localhost/1,2,...,300/foo/"
When adjusting these limits:
- Increase values gradually rather than setting extremely high numbers
- Consider security implications of larger buffer sizes
- Document these non-default settings for future maintenance
- Test performance impact under load
While working with Apache's mod_rewrite, I encountered a puzzling limitation: rewrite rules fail silently when the parameter length exceeds 255 characters. The server returns a 403 Forbidden error without any rewrite log entries, making debugging particularly challenging.
After extensive testing, I discovered this isn't actually a mod_rewrite limitation, but rather a security feature in Apache called LimitRequestLine
. By default, Apache restricts the maximum size of the HTTP request line to 8190 bytes, but some Linux distributions set lower limits in their default configurations.
# Check current limit in your Apache configuration
grep LimitRequestLine /etc/apache2/apache2.conf
Here are three approaches to resolve this:
1. Increasing LimitRequestLine
# In your Apache configuration (httpd.conf or apache2.conf)
LimitRequestLine 16384 # Double the default value
2. Alternative Rewrite Approach
For systems where you can't modify server configuration:
RewriteEngine On
RewriteCond %{REQUEST_URI} ^/([0-9,]{256,})/foo/$
RewriteRule ^ /foo.php?id=%1 [L,QSA,NE]
3. Using PATH_INFO Instead
RewriteRule ^/([\\d,]+)/foo/$ /foo.php/$1 [L]
# Then in PHP:
$path = explode('/', $_SERVER['PATH_INFO']);
$ids = $path[1];
Different web servers handle this differently:
- Nginx: No default limit on request line length
- IIS: Default limit of 16K
- Lighttpd: Configurable via server.max-request-size
When dealing with long parameters:
- Consider using POST instead of GET for large data transfers
- Implement pagination or chunking for extremely large parameter sets
- Validate input length in your application code
- Monitor your server logs for 403 errors
To properly diagnose such issues:
# Enable full rewrite logging
RewriteLog "/var/log/apache2/rewrite.log"
RewriteLogLevel 9
LogLevel debug