Symptoms
- The WordPress homepage loads correctly.
- All other pages, posts, categories, and links return a 404 error.
- The problem occurs after a migration, hosting change, or modification to the
.htaccessfile.
Cause
WordPress uses the .htaccess file to handle friendly URLs (permalinks). When this file doesn't exist, is empty, or is missing the necessary rewrite directives, the server cannot properly redirect requests to WordPress's index.php file.
Solution
Step 1: Restore WordPress Directives in .htaccess
Access your site files using your control panel's File Manager (cPanel or DirectAdmin) or via FTP.
Locate the .htaccess file in the root of your WordPress installation (where wp-config.php is located).
Note: The .htaccess file is a hidden file. In the File Manager, enable the option to show hidden files.
If the file doesn't exist, create it. Then add or replace the content with the following basic WordPress directives:
# 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
Save the file.
Step 2: Verify File Permissions
Make sure the .htaccess file has the correct permissions:
- Recommended permissions:
444(read-only) - Owner: your hosting user
In cPanel or DirectAdmin, you can change permissions by right-clicking the file and selecting "Permissions" or "Change Permissions".
Step 3: Verify the Problem is Resolved
Visit any page or post on your site. If everything works correctly, the problem is resolved.
WordPress in a Subdirectory
If WordPress is installed in a subdirectory (e.g., yourdomain.com/blog/), modify RewriteBase and the last rule:
# BEGIN WordPress
RewriteEngine On
RewriteRule .* - [E=HTTP_AUTHORIZATION:%{HTTP:Authorization}]
RewriteBase /blog/
RewriteRule ^index\.php$ - [L]
RewriteCond %{REQUEST_FILENAME} !-f
RewriteCond %{REQUEST_FILENAME} !-d
RewriteRule . /blog/index.php [L]
# END WordPress
Replace /blog/ with your subdirectory name.
Directive Explanation
| Directive | Function |
|---|---|
RewriteEngine On |
Enables the URL rewriting engine. |
RewriteRule .* - [E=HTTP_AUTHORIZATION:%{HTTP:Authorization}] |
Preserves the HTTP authorization header for the REST API. |
RewriteBase / |
Defines the base for rewrite rules. |
RewriteRule ^index\.php$ - [L] |
If the request is for index.php, do nothing else. |
RewriteCond %{REQUEST_FILENAME} !-f |
Condition: the requested file doesn't physically exist. |
RewriteCond %{REQUEST_FILENAME} !-d |
Condition: the requested directory doesn't physically exist. |
RewriteRule . /index.php [L] |
Redirect all requests that meet the conditions to index.php. |
Troubleshooting
Error Persists After Adding Directives
- Verify that the
.htaccessfile is in the WordPress root (same directory aswp-config.php). - Confirm that the directives are correctly copied, without extra spaces or characters.
- Contact your hosting provider to verify that the
mod_rewritemodule is enabled.
The .htaccess File Gets Overwritten or Modified
If the .htaccess file gets overwritten after adding the directives, this may indicate:
-
A plugin interfering: Some caching, security, or SEO plugins modify
.htaccess. Review recently installed plugins or temporarily deactivate them to identify the culprit. -
Malware on the site: Malware frequently modifies
.htaccessto inject malicious redirects. Scan your site for infected files and review access logs for suspicious activity.