Web Server Advanced

Resolving Apache AllowOverride None Ignoring .htaccess in Subdirectories on Ubuntu 22.04 LTS

Troubleshoot why Apache ignores .htaccess files in subdirectories on Ubuntu 22.04 LTS. Learn to configure AllowOverride for proper site functionality and security.

👨‍💻
Senior Systems Architect • Verified in Staging Labs

Troubleshoot why Apache ignores .htaccess files in subdirectories on Ubuntu 22.04 LTS. Learn to configure AllowOverride for proper site functionality and security.

When deploying web applications such as WordPress, Laravel, or custom PHP applications on an Apache web server, you often rely on .htaccess files for URL rewriting (pretty permalinks), custom redirects, authentication, or directory-specific configurations. A common and frustrating issue is when these .htaccess files appear to be completely ignored by Apache, especially in subdirectories, leading to 404 errors, 403 errors, or unexpected behavior despite the files being correctly placed. This guide will walk you through diagnosing and resolving this issue on Ubuntu 22.04 LTS.

Symptom & Error Signature

The most prominent symptom is the lack of expected behavior from your .htaccess rules. You might observe:

  • 404 Not Found errors when trying to access custom URLs (e.g., WordPress permalinks, Laravel routes) that should be handled by mod_rewrite rules in .htaccess.
  • 403 Forbidden errors when attempting to access a directory that should be protected by AuthType Basic directives in .htaccess.
  • Directory listings appearing in subdirectories where Indexes should have been disabled by .htaccess.
  • Incorrect content delivery or server errors due to PHP settings or custom MIME types defined in .htaccess not being applied.

While there isn't typically a direct error signature in Apache's error.log when .htaccess is ignored (Apache simply doesn't process it), you might see related errors from the consequence of the file being ignored, for example:

[Sat Sep 04 10:30:01.123456 2026] [php:error] [pid 12345] [client 192.168.1.100:54321] PHP Fatal error: Uncaught Error: Call to undefined function custom_function() in /var/www/html/app/index.php:10
[Sat Sep 04 10:30:02.123456 2026] [core:info] [pid 12346] [client 192.168.1.101:67890] AH00128: File does not exist: /var/www/html/wp-content/uploads/2023/01/image.jpg
[Sat Sep 04 10:30:03.123456 2026] [authz_core:error] [pid 12347] [client 192.168.1.102:98765] AH01630: client denied by server configuration: /var/www/html/admin/

The above log entries show the results of .htaccess being ignored, not the ignoring itself. The File does not exist for wp-content/uploads could be a symptom if a rewrite rule should have handled it. A 403 could be a symptom if .htaccess was supposed to grant access, or if it was supposed to redirect to a login page instead of just denying.

Root Cause Analysis

The primary reason Apache ignores .htaccess files in subdirectories (or any directory) is the AllowOverride directive set to None within a relevant <Directory> block in your Apache configuration.

On Ubuntu 22.04 LTS, the default Apache configuration for /var/www/html (which is often your document root) typically includes a <Directory> block in /etc/apache2/apache2.conf or a virtual host file, explicitly setting AllowOverride None.

Here's why this happens:

  1. Security Best Practice: Historically, AllowOverride None has been the default for security reasons. Allowing .htaccess files gives users (or potentially attackers who gain limited access to your web directory) the ability to override server configurations, which can introduce security vulnerabilities if not properly managed.
  2. Performance: Apache must search for and parse .htaccess files in every directory on the path to a requested resource if AllowOverride is enabled. This lookup process adds a slight performance overhead. For high-traffic sites, it's generally recommended to move all .htaccess rules into the main Apache configuration files (apache2.conf or virtual host files) where possible, eliminating the need for AllowOverride altogether.
  3. Default Configuration: When you install Apache on Ubuntu, the global apache2.conf often contains a <Directory /var/www/> block with AllowOverride None. If your virtual host's document root falls within this path and doesn't explicitly override it, or if your virtual host itself has AllowOverride None set for its document root, then .htaccess files will be ignored.

When AllowOverride None is set, Apache will not even look for .htaccess files in the specified directory or its subdirectories. All directives within those .htaccess files are simply disregarded.

Step-by-Step Resolution

To resolve this issue, you need to modify the AllowOverride directive in your Apache configuration files.

1. Locate the Relevant Apache Configuration File

First, identify which Apache configuration file controls your website's document root.

  • Global Configuration: For basic setups or if you're using the default /var/www/html document root without a dedicated virtual host, the primary file to check is /etc/apache2/apache2.conf.
  • Virtual Host Configuration: If you have virtual hosts set up (e.g., for yourdomain.com), the relevant configuration will be in its virtual host file, typically located in /etc/apache2/sites-available/yourdomain.conf (or similar).

Use ls -l /etc/apache2/sites-enabled/ to see which virtual hosts are currently active.

2. Identify the AllowOverride None Directive

Open the relevant configuration file(s) with a text editor (e.g., nano or vim).

For the global configuration:

sudo nano /etc/apache2/apache2.conf

For a specific virtual host (replace yourdomain.conf with your actual file name):

sudo nano /etc/apache2/sites-available/yourdomain.conf

Search for a <Directory> block that corresponds to your website's document root (e.g., /var/www/html, /var/www/yourdomain.com). Within this block, look for the AllowOverride directive. It will likely be set to None.

Example Snippet (from apache2.conf):

#
# Possible values for the Options directive are "All", "None", and any combination of:
#   Indexes Includes FollowSymLinks SymLinksIfOwnerMatch ExecCGI MultiViews
#
# The Options directive controls which server features are available in a
# particular directory.
#
# AllowOverride controls what directives may be placed in .htaccess files.
# It can be "All", "None", or any combination of the keywords:
#   AuthConfig FileInfo Indexes Limit Options
#
<Directory /var/www/>
    Options Indexes FollowSymLinks
    AllowOverride None
    Require all granted
</Directory>

# You might also have a specific block for /var/www/html
<Directory /var/www/html/>
    Options Indexes FollowSymLinks
    AllowOverride None # <-- THIS IS THE CULPRIT!
    Require all granted
</Directory>

3. Modify AllowOverride to All (or Specific Directives)

Change AllowOverride None to AllowOverride All. This tells Apache to process any .htaccess file it finds in that directory and its subdirectories, allowing all types of directives.

Setting AllowOverride All allows users to override almost any server configuration via .htaccess. While convenient, this can be a security risk if untrusted users have write access to your web directory. For production environments, consider using more specific values like AllowOverride FileInfo AuthConfig if you only need URL rewriting and authentication.

  • FileInfo: Allows mod_rewrite directives (e.g., RewriteRule, RewriteCond).
  • AuthConfig: Allows authentication directives (e.g., AuthUserFile, AuthType, Require).
  • Indexes: Allows Options Indexes or -Indexes directives.
  • Limit: Allows Limit directives for access control.
  • Options: Allows Options directives (e.g., MultiViews, ExecCGI, SymLinksIfOwnerMatch).

Modified Example:

<Directory /var/www/html/>
    Options Indexes FollowSymLinks
    # Change 'None' to 'All' or specific directives
    AllowOverride All
    # AllowOverride FileInfo AuthConfig # <-- More secure option if you only need rewrite and auth
    Require all granted
</Directory>

Save the changes to the configuration file (e.g., Ctrl+X, then Y, then Enter for nano).

4. Enable mod_rewrite (if necessary)

Many applications that rely on .htaccess for custom URLs (like WordPress permalinks) require Apache's mod_rewrite module. Ensure it's enabled:

sudo a2enmod rewrite

You should see output similar to: Enabling module rewrite. To activate the new configuration, you need to run: systemctl restart apache2

5. Test Configuration and Restart Apache

Before restarting Apache, always test your configuration for syntax errors.

sudo apache2ctl configtest

If the output is Syntax OK, you can safely restart Apache. If there are errors, carefully review your changes.

sudo systemctl restart apache2

A full restart (systemctl restart apache2) is necessary for AllowOverride changes and new module activations to take effect. A reload might not be sufficient.

6. Verify Functionality

After restarting Apache, clear your browser cache and attempt to access the URLs or directories that were previously causing issues. Your .htaccess rules should now be processed correctly.

If you are still experiencing issues, double-check:

  • The exact path in your <Directory> block matches your website's document root.
  • There are no conflicting AllowOverride directives.
  • Your .htaccess file itself has correct syntax.
  • Apache has read permissions for the .htaccess file and its containing directories.

By carefully following these steps, you should successfully resolve the issue of Apache ignoring .htaccess files in subdirectories on your Ubuntu 22.04 LTS server. Remember to prioritize security by using the most specific AllowOverride directives possible in production environments.

👨‍💻

Johnathon Wheeler

Senior Systems Architect & DevOps Engineer • Austin, TX

Connect on LinkedIn

Johnathon has over 16 years of hands-on experience designing, debugging, and scaling Linux web hosting stacks, container clusters, and high-availability database architectures. Every guide on ButItWorkedLocal is independently tested against Debian 12, Ubuntu 24.04/22.04 LTS, Rocky Linux, and Docker environments to guarantee reproducibility in production.

🛡️

Our Production Verification Guarantee

Encountering a bug not covered here or running a non-standard kernel configuration? Our solutions are continually refined against real production incidents. Submit an environment trace for our editorial team to replicate.