Fix Root .htaccess Inheritance on Hostinger Subdomains

by Fahim

You spin up a WordPress subdomain on Hostinger for staging or testing, visit the URL, and immediately hit a wall: your subdomain serves a 404 rendered in your main site’s theme, gets trapped in an infinite redirect loop, or throws a 500 error. The culprit is almost always your parent directory’s .htaccess quietly hijacking requests before your subdomain’s configuration ever runs. Here is how to isolate your rewrite scopes and fix it for good.

Fix Root .htaccess Inheritance on Hostinger Subdomains
Fix Root .htaccess Inheritance on Hostinger Subdomains

The Nested Document Root Problem on Hostinger

By default, Hostinger’s hPanel drops new subdomains right inside your primary site’s document root. If your apex site lives at public_html/, your new staging or API subdomain defaults to public_html/sub/.

Both Apache and OpenLiteSpeed read configurations hierarchically. The server parses public_html/.htaccess before it ever looks inside public_html/sub/.htaccess. Any rewrite rule, canonical redirect, or security header defined for your main domain cascades down into the child folder unless you explicitly tell the engine to stop.

In practice, that inheritance bites you in three ways:

  • Permalink hijacking: Any request to the subdomain that doesn’t hit an existing file gets swept up by the root site’s WordPress router, leaving you with a 404 straight out of your main site’s theme.
  • Redirect loops: Aggressive force-HTTPS or non-WWW rules on the apex domain intercept requests to your subdomain host and bounce visitors back and forth endlessly.
  • Security plugin bleed: Hardened security directives from plugins like Wordfence or iThemes on the root site end up blocking REST API calls and static assets inside your subdomain.

Check What the Root .htaccess Is Actually Running

Before editing anything, pull up your root .htaccess and check what rules are currently firing. SSH into your instance or pop open the hPanel File Manager.

Run this in your terminal to see the root rewrite block:

# Navigate to the primary website root
cd ~/domains/yourdomain.com/public_html # Print the active rewrite rules
cat .htaccess | grep -E -A 10 "RewriteEngine|RewriteRule"

Standard WordPress root files usually look something like this:

# BEGIN WordPress

RewriteEngine On
RewriteRule .* - [E=HTTP_AUTHORIZATION:%{HTTP:Authorization}]
RewriteBase /
RewriteRule ^index.php$ - [L]
RewriteCond %{REQUEST_FILENAME} !-f
RewriteCond %{REQUEST_FILENAME} !-d
RewriteRule . /index.php [L]

# END WordPress

Notice RewriteCond %{REQUEST_FILENAME} !-d. When a request hits sub.yourdomain.com/sample-page/, the server checks whether public_html/sample-page/ exists as a folder. It doesn’t, so the parent rule triggers and shunts the request straight into the root site’s index.php instead of letting the subdomain route it.

Method 1: Stop Parent Rewrites from Processing the Subdirectory

If you don’t want to move files around, the fastest fix is telling the root .htaccess to ignore the subdomain folder entirely. You stick an exclusion rule right above the main WordPress rewrite block.

Open public_html/.htaccess and drop this rule right before your standard WordPress directives:


RewriteEngine On # Exclude subdomain directory from parent rewrites
RewriteRule ^(sub|staging|app)(/.*)?$ - [L] # Standard WordPress rewrites continue below
RewriteRule .* - [E=HTTP_AUTHORIZATION:%{HTTP:Authorization}]
RewriteBase /
RewriteRule ^index.php$ - [L]
RewriteCond %{REQUEST_FILENAME} !-f
RewriteCond %{REQUEST_FILENAME} !-d
RewriteRule . /index.php [L]

The - [L] flag tells the rewrite engine to stop dead in its tracks if the request path matches your subdomain’s folder. If you recently moved your site using our guide to migrate WordPress to Hostinger via SSH and Rsync, verify that your synchronized root rules didn’t overwrite this exclusion block during deployment.

Method 2: Reset the Subdomain .htaccess Engine

Even if the parent engine skips matching directories, child directories can still inherit environment variables and rewrite options. You can force a clean slate directly inside public_html/sub/.htaccess.

Update or replace your subdomain’s .htaccess with this isolated block:

# Isolate subdomain rewrite engine

RewriteEngine On
RewriteBase / # Stop rule inheritance from parent directories
RewriteOptions None # Prevent authorization headers from leaking
RewriteRule .* - [E=HTTP_AUTHORIZATION:%{HTTP:Authorization}] # Subdomain WordPress routing
RewriteRule ^index.php$ - [L]
RewriteCond %{REQUEST_FILENAME} !-f
RewriteCond %{REQUEST_FILENAME} !-d
RewriteRule . /index.php [L]

As noted in the Apache mod_rewrite documentation, setting RewriteOptions None blocks behaviors like Inherit and InheritBefore, so your child folder won’t merge the parent’s rule table into its own execution loop.

Fixing HTTPS and WWW Redirect Clashes

Another classic issue on Hostinger is a blanket HTTPS rule in the root directory that catches every host header. If your root config forces https://yourdomain.com without filtering hostnames, anyone browsing to http://sub.yourdomain.com gets punted directly to the main site’s homepage.

Look through your root .htaccess for unconstrained canonical redirects and tie them explicitly to your apex domain:


RewriteEngine On # Enforce HTTPS only on the apex domain and www
RewriteCond %{HTTPS} off
RewriteCond %{HTTP_HOST} ^(www.)?yourdomain.com$ [NC]
RewriteRule ^(.*)$ https://yourdomain.com/$1 [R=301,L]

Matching against %{HTTP_HOST} ensures requests for sub.yourdomain.com skip the block entirely. If you manage DNS externally, check out how to point Namecheap DNS to Hostinger to confirm your A records are hitting the right server IP in the first place.

The Better Architecture: Decouple Document Roots in hPanel

Nesting sites inside each other is messy. You end up with permission quirks, backup bloat, and cache bleed. The cleanest long-term fix is pulling the subdomain document root completely out of public_html/.

hPanel lets you choose a custom folder when setting up a subdomain. Instead of accepting the default nested path, map it side-by-side with public_html.

  1. Log in to your Hostinger hPanel.
  2. Go to Websites > Subdomains.
  3. Under Create a New Subdomain, check Custom folder for subdomain.
  4. Set the path to domains/yourdomain.com/subdomain_html instead of the nested default.
  5. Click Create.

Now, move your subdomain files to the clean folder over SSH:

# Move files from old nested location to parallel directory
mv ~/domains/yourdomain.com/public_html/sub/* ~/domains/yourdomain.com/subdomain_html/ # Move hidden configuration files
mv ~/domains/yourdomain.com/public_html/sub/.htaccess ~/domains/yourdomain.com/subdomain_html/ # Clean up empty legacy directory
rmdir ~/domains/yourdomain.com/public_html/sub

Because subdomain_html sits outside public_html, the web server never touches the root .htaccess when serving subdomain requests. No inheritance, no workarounds needed.

Handling OpenLiteSpeed Cache Directive Leaks

Hostinger’s OpenLiteSpeed stack uses native cache modules configured via tags. When folders are nested, cache tags on the apex site can bleed into the subdomain, returning weird headers or stale pages.

If you set up caching following our walkthrough to enable Redis object cache in Hostinger hPanel, make sure each WordPress site uses a unique Redis database index in wp-config.php (database 0 for root, database 1 for subdomain):

// Define distinct Redis database prefix in subdomain wp-config.php
define('WP_REDIS_DATABASE', 1);
define('WP_CACHE_KEY_SALT', 'subdomain_');

To keep parent LiteSpeed cache rules from trickling down, drop a cache purge marker into public_html/sub/.htaccess:


CacheLookup on
RewriteEngine On
# Isolate LSCache tags to this instance
RewriteRule .* - [E=Cache-Control:no-autocache]

You can dig deeper into tag-based purging in the LiteSpeed Tech Documentation.

Verify Your Fix from the Command Line

Don’t rely on your browser to test redirects. Browsers cache 301 redirects aggressively, which will fool you into thinking an old bug is still active. Test straight from your terminal with curl to see real response headers:

curl -ILs -o /dev/null -w %{http_code}" "%{redirect_url}"n" https://sub.yourdomain.com/sample-page/

A working setup will hand you a direct 200 for valid pages, or a subdomain-branded 404—never a 301 redirect pointing back to your main site. If you hit file upload errors once routing is sorted, check our guide to fix ‘The link you followed has expired’ in WordPress to verify your PHP limits on the sub-site.

Frequently Asked Questions

Why does my subdomain show the parent WordPress theme?

Your root .htaccess is catching requests meant for your subdomain and sending them through the root index.php. Because that URI doesn’t exist on the main site, WordPress handles it as a standard 404 and displays the main theme’s template. Adding RewriteRule ^subfolder(/.*)?$ - [L] to your root .htaccess stops the parent site from processing those requests.

Does moving my subdomain out of public_html break my SSL certificate?

No. Let’s Encrypt certificates in hPanel bind to the virtual host domain mapping, not the folder path on disk. As long as your DNS A record points to the server and the virtual host is configured, your SSL certificate stays intact.

Can I use RewriteOptions Inherit if I want some rules shared?

You can, but I wouldn’t recommend it with WordPress. Dynamic front-controller routing relies heavily on strict rewrite matching. Inheriting rules from a parent WordPress installation almost always breaks custom permalinks or REST endpoints on the child site.

What should I do if hPanel does not let me change the document root?

On some legacy Hostinger shared packages, hPanel forces subdomains into public_html subfolders. If that’s what you have, combine Method 1 (excluding the folder in the root .htaccess) with Method 2 (setting RewriteOptions None in the subdomain’s .htaccess). That locks down the scopes without needing root folder access.

all_in_one_marketing_tool