Introduction
Apache's mod_rewrite in .htaccess files is commonly used to detect mobile user agents and redirect to mobile-specific pages. When the RewriteCond pattern fails to match, mobile users receive the desktop version instead. The issue is typically caused by incorrect regex syntax, missing case-insensitive flags, or the order of conditions in the rule chain.
Symptoms
- Mobile devices are not redirected to the mobile site version
RewriteCond %{HTTP_USER_AGENT}patterns appear to never match- Desktop version loads on phones and tablets
- Apache rewrite log (if enabled) shows the condition evaluation skipping the mobile check
- The rule works in online regex testers but fails on the actual server
Common Causes
- Missing
[NC](no-case) flag causing case-sensitive matching on user agent strings - Special regex characters in user agent strings not properly escaped
- Multiple
RewriteCondlines default to AND logic when OR is needed HTTP_USER_AGENTvariable not available in certain Apache contextsmod_rewritenot enabled or.htaccessoverrides not permitted
Step-by-Step Fix
- 1.Verify mod_rewrite is enabled and .htaccess is processed:
- 2.```apache
- 3.# In the VirtualHost or directory context
- 4.<Directory /var/www/html>
- 5.AllowOverride All
- 6.Require all granted
- 7.</Directory>
- 8.
` - 9.Then check if mod_rewrite is loaded:
- 10.```bash
- 11.apachectl -M | grep rewrite
- 12.
` - 13.Fix the mobile user agent detection with proper flags:
- 14.```apache
- 15.RewriteEngine On
# Check for common mobile user agents (case-insensitive, OR logic)
RewriteCond %{HTTP_USER_AGENT} "android|iphone|ipad|ipod|blackberry|windows phone|opera mini|opera mobi|iemobile|mobile|silk" [NC]
RewriteCond %{HTTP_HOST} !^m\. [NC]
RewriteCond %{QUERY_STRING} !^desktop [NC]
RewriteRule ^(.*)$ https://m.example.com/$1 [R=302,L]
``
Key fixes: [NC] flag for case-insensitive matching, proper alternation with |` inside quotes, and checking the query string to allow desktop override.
- 1.Use OR logic for multiple separate conditions if not using alternation:
- 2.```apache
- 3.RewriteCond %{HTTP_USER_AGENT} "android" [NC,OR]
- 4.RewriteCond %{HTTP_USER_AGENT} "iphone" [NC,OR]
- 5.RewriteCond %{HTTP_USER_AGENT} "ipad" [NC]
- 6.RewriteRule ^(.*)$ https://m.example.com/$1 [R=302,L]
- 7.
` - 8.Each condition must have
[OR]except the last one in the chain. - 9.Enable rewrite logging for debugging (Apache 2.4+):
- 10.```apache
- 11.LogLevel alert rewrite:trace3
- 12.
` - 13.Then check the error log:
- 14.```bash
- 15.tail -f /var/log/apache2/error.log | grep rewrite
- 16.
` - 17.This shows each condition evaluation and whether it matched.
- 18.Test with curl using a mobile user agent:
- 19.```bash
- 20.curl -I -A "Mozilla/5.0 (iPhone; CPU iPhone OS 17_0 like Mac OS X)" http://example.com/page 2>&1 | grep -E "HTTP|Location"
- 21.
` - 22.Expected:
HTTP/1.1 302 FoundwithLocation: https://m.example.com/page.
Prevention
- Consider using responsive design instead of user agent-based redirects for a more maintainable approach
- Keep a comprehensive mobile user agent list and update it quarterly as new devices emerge
- Use
[R=302](temporary redirect) during testing, switch to[R=301](permanent) only after confirming correct behavior - Add a
?desktopquery string bypass for testing the desktop site on mobile devices - Monitor the ratio of mobile-to-desktop requests in your access logs to detect detection failures
- Test with real device user agent strings from user analytics data, not just synthetic test strings