Errors
How to Fix WordPress 404 Errors on All Pages Except Homepage
If your WordPress homepage loads without any problems, but clicking any inner link—like a blog post, product page, or contact form—leads directly to a "404 Not Found" error page, your server's rewrite rules or WordPress permalink settings are misconfigured. In almost all cases, WordPress has lost the ability to route incoming URLs through its central index file. You can usually solve this in seconds by navigating to Settings > Permalinks in your admin dashboard and clicking Save Changes to flush the rewrite rules.
When that quick trick fails, the issue lies deeper in server config files like .htaccess or Nginx virtual host files, missing Apache modules, or file permission locks. Below, we break down why this happens and walk through every safe step to restore your site's links completely.
What You Are Seeing (and What It Means)
When you encounter this specific issue, the homepage works normally because web servers automatically look for index.php or index.html at the site root folder when no subfolder or path is provided in the address bar. However, inner pages rely on dynamic URL routing managed by WordPress standard permalinks.
Typical symptoms include:
- The Homepage Loads Fine: Your main domain (e.g.,
https://example.com) renders cleanly with all images, styles, and layout elements intact. - Every Subpage Returns 404: Clicking any internal link (such as
https://example.com/about/orhttps://example.com/sample-post/) brings up either a server-level "404 Not Found" page or your theme's custom 404 template. - Plain Permalinks Work: If you test a raw URL structure like
https://example.com/?p=123, the page loads normally, confirming that the content still exists in your database and that only human-readable "pretty" URLs are failing.
Why Is This Happening?
WordPress uses a process called URL rewriting. When a user visits a custom permalink like /contact/, the web server checks if a physical file or directory named "contact" exists on the hard drive. Because it doesn't, the web server needs to silently pass that request to index.php, which then queries your database and displays the correct page.
When every inner page throws a 404 error, that silently rewritten route has broken down. The primary causes include:
- Corrupted or Missing
.htaccessFile: On Apache and LiteSpeed web servers, routing rules live in a hidden file called.htaccessin your site root. If this file was deleted, modified by a caching or security plugin, or stripped during a migration, dynamic routes fail. - Unwritten Rewrite Cache: WordPress stores rewrite rules in the database. Updating plugins, changing custom post types, or migrating to a new host can leave this cache out of sync with the server.
- Missing Nginx Directives: Nginx web servers do not read
.htaccessfiles. If your host moved your site to an Nginx environment without adding the standardtry_filesdirective to the server configuration, every subpage will return a hard server 404 error. - Disabled Server Modules (Apache): If Apache’s
mod_rewritemodule is turned off, or ifAllowOverrideis set toNonein the server configuration, Apache ignores the instructions inside.htaccess.
Always back up your site before modifying server files or changing core site settings. If an update recently broke your site or you suspect multiple files are corrupt, review our guide on how to recover when WordPress breaks after an update.
Step-by-Step Fixes for 404 Permalink Errors
Work through these steps in order. They start with the easiest, safest dashboard-based solutions before moving to server configuration checks.
Step 1: Save Permalinks in the Dashboard (The 10-Second Fix)
In most instances, flushing the WordPress internal rewrite cache immediately restores all inner pages. You do not need to change any text fields to execute this flush.
- Log into your WordPress admin dashboard.
- Go to Settings > Permalinks in the left sidebar menu.
- Note your current permalink structure (usually Post name).
- Scroll down to the bottom of the page without changing any settings and click Save Changes.
- Open a new browser window (or incognito tab) and test your inner pages.
When you click "Save Changes," WordPress recreates its internal database routing table and attempts to rewrite the rule set to your server's configuration file. If this resolves the issue, you're done!
Step 2: Rebuild the .htaccess File (Apache or LiteSpeed)
If saving your permalinks does not solve the problem or shows a notice that your .htaccess file is not writable, the file may be corrupt or locked by incorrect file permissions.
To rebuild a clean default .htaccess file using your web host's File Manager or SFTP client:
- Connect to your web host using SFTP or open your hosting control panel's File Manager (e.g., cPanel or Plesk).
- Navigate to your WordPress site root directory (typically
public_htmlorwww). - Locate the
.htaccessfile. Because files starting with a dot are hidden by default, enable "Show Hidden Files" in your FTP client or File Manager settings. - Rename the existing file to
.htaccess_oldto keep a backup copy. - Create a brand-new file named
.htaccessin the same root folder. - Paste the default WordPress core rules into the new file:
# BEGIN WordPress
<IfModule mod_rewrite.c>
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]
</IfModule>
# END WordPress
- Save the file and set its permissions to
0644(rw-r--r--). - Return to Settings > Permalinks in your WordPress dashboard and click Save Changes again.
If page content still fails to load or gives permission errors, check if you have severe hosting-level issues using our troubleshooting guide for WordPress 500 internal server errors.
Step 3: Fix Nginx Web Server Configuration
Because Nginx does not use .htaccess, editing or saving permalinks in WordPress will have no effect if the host's Nginx configuration is missing the proper routing rule. If your server uses Nginx, you must make sure your server block file includes the try_files instruction inside the primary location block.
In your Nginx site configuration file (typically located at /etc/nginx/sites-available/yourdomain.conf), ensure the location block looks like this:
location / {
try_files $uri $uri/ /index.php?$args;
}
This directive instructs Nginx to first look for a real file matching the URL ($uri), then a real directory ($uri/). If neither is found, it safely forwards the request to /index.php with all original query arguments attached. Once added, test the Nginx configuration with sudo nginx -t and reload Nginx with sudo systemctl reload nginx.
Note: On managed WordPress hosts like Kinsta, WP Engine, or SiteGround, you will not have direct access to Nginx configuration files. If you run Nginx on a managed host and permalink flushes fail, contact your hosting support to reset your site's Nginx rewrite rules.
Step 4: Verify Apache mod_rewrite and AllowOverride Settings
If you run an unmanaged virtual private server (VPS) with Apache (such as DigitalOcean, AWS EC2, or Linode), your site may produce 404 errors on subpages because Apache is overriding or ignoring your .htaccess file.
First, ensure the rewrite module is enabled by running this terminal command:
sudo a2enmod rewrite
sudo systemctl restart apache2
Second, check your main Apache virtual host file or apache2.conf file. Locate the directory block pointing to your web root and ensure AllowOverride is set to All instead of None:
<Directory /var/www/html/>
Options Indexes FollowSymLinks
AllowOverride All
Require all granted
</Directory>
If AllowOverride is set to None, Apache ignores your .htaccess file completely, causing all permalinks outside the homepage to throw 404 errors.
Step 5: Address Plugin and Custom Post Type Conflicts
If you recently added a custom post type via a plugin or custom child theme code, improper post type registration can break routing for those specific items or conflict with general site permalinks.
When registering custom post types in PHP, developers must call the registration function inside the init hook without manually calling flush_rewrite_rules() on every page load. If a security or custom post type plugin mismanages custom rewrite tags, temporarily disable custom plugins to see if regular permalinks return.
If you recently upgraded server environments or upgraded PHP versions and noticed new script conflicts, see our step-by-step guide on fixing WordPress errors after a PHP upgrade.
How to Prevent WordPress Permalinks from Breaking
Once your site links are functioning properly, take these steps to ensure routing problems don't return during future updates or migrations:
- Avoid Unnecessary
flush_rewrite_rules()Calls: If you build custom plugins or themes, never callflush_rewrite_rules()on every page load inside functions.php. Execute it strictly during plugin activation or deactivation hooks. - Lock Down
.htaccessFile Permissions: Ensure your.htaccessfile uses standard file permissions (0644). This prevents unauthorized scripts from altering core web routing while allowing WordPress core to make legitimate updates. - Check Server Files After Migrations: When migrating a site from a staging area to a live domain, always double-check that your migration plugin correctly synced hidden files like
.htaccessand updated the site URL parameters in the database. - Keep Up to Date with Server Changes: If your web host changes server engines (for instance, moving from Apache to Nginx reverse-proxy setups), confirm that rewrite rules were migrated properly. If you need to safely rollback plugin updates or server changes during maintenance, read our guide on how to downgrade a WordPress plugin or theme safely.
When to Call a Professional
While resaving permalinks fixes 404 errors on inner pages 90% of the time, server-level file overrides, corrupt databases, complex reverse proxies, and stubborn multisite configuration failures can take hours to isolate if you don't work with server configurations daily.
If you've tried saving your permalinks, rebuilt your .htaccess file, verified server directives, and still find yourself staring at 404 errors across your site, let an expert fix it safely without taking your site down.
At Mend, our senior WordPress engineers diagnose and repair site routing issues quickly on a backup-first workflow. If you need immediate expert help restoring your site, submit a Quick Fix request or start with a free diagnosis through Mend's free Diagnosis service to get a plain-English explanation and flat upfront quote with zero risk.
Frequently asked questions
Why do plain URLs like ?p=123 work when custom permalinks show 404?
Plain URLs bypass server-level rewrite rules entirely by feeding the database query parameter directly to index.php. Custom "pretty" permalinks rely on .htaccess or Nginx rewrite directives to translate the human-readable slug back into a database query.
Will saving my permalinks cause any downtime or break existing links?
No. Clicking "Save Changes" under Settings > Permalinks simply forces WordPress to flush its internal rewrite cache and update the .htaccess routing rules. It will not delete content or change your established page structures.
Why did all my WordPress pages give 404 errors after moving to a new host?
Site migrations often leave out hidden files like .htaccess, or the new host may use Nginx instead of Apache without having standard URL rewrite rules configured in the server block.
How do file permissions affect WordPress 404 permalink errors?
If the .htaccess file has incorrect permissions (such as being locked as read-only by root), WordPress cannot write essential routing instructions to it when you update site settings, leaving the server unable to route inner page requests.