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 RewriteCond lines default to AND logic when OR is needed
  • HTTP_USER_AGENT variable not available in certain Apache contexts
  • mod_rewrite not enabled or .htaccess overrides not permitted

Step-by-Step Fix

  1. 1.Verify mod_rewrite is enabled and .htaccess is processed:
  2. 2.```apache
  3. 3.# In the VirtualHost or directory context
  4. 4.<Directory /var/www/html>
  5. 5.AllowOverride All
  6. 6.Require all granted
  7. 7.</Directory>
  8. 8.`
  9. 9.Then check if mod_rewrite is loaded:
  10. 10.```bash
  11. 11.apachectl -M | grep rewrite
  12. 12.`
  13. 13.Fix the mobile user agent detection with proper flags:
  14. 14.```apache
  15. 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. 1.Use OR logic for multiple separate conditions if not using alternation:
  2. 2.```apache
  3. 3.RewriteCond %{HTTP_USER_AGENT} "android" [NC,OR]
  4. 4.RewriteCond %{HTTP_USER_AGENT} "iphone" [NC,OR]
  5. 5.RewriteCond %{HTTP_USER_AGENT} "ipad" [NC]
  6. 6.RewriteRule ^(.*)$ https://m.example.com/$1 [R=302,L]
  7. 7.`
  8. 8.Each condition must have [OR] except the last one in the chain.
  9. 9.Enable rewrite logging for debugging (Apache 2.4+):
  10. 10.```apache
  11. 11.LogLevel alert rewrite:trace3
  12. 12.`
  13. 13.Then check the error log:
  14. 14.```bash
  15. 15.tail -f /var/log/apache2/error.log | grep rewrite
  16. 16.`
  17. 17.This shows each condition evaluation and whether it matched.
  18. 18.Test with curl using a mobile user agent:
  19. 19.```bash
  20. 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. 21.`
  22. 22.Expected: HTTP/1.1 302 Found with Location: 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 ?desktop query 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