404 Not Found on Posts and Pages
HTTP 404

404 Not Found on Posts and Pages

Elena Rodriguez ·

Symptoms

You click a post link and get a 404 page — but the post is right there in your dashboard, published and everything. This is one of the most common WordPress issues, and nine times out of ten it’s a permalink rewrite problem, not a missing page. The right way to fix this is to work through the causes methodically instead of randomly toggling settings.

What Causes 404 Not Found on Posts and Pages?

  1. Corrupted .htaccess file — WordPress writes rewrite rules to .htaccess (on Apache). If this file gets corrupted, deleted, or has wrong permissions, every URL except the homepage breaks.
  2. Permalink settings out of sync — A plugin, theme switch, or manual database edit can desync the permalink structure WordPress expects from what’s actually written to the server config.
  3. Missing mod_rewrite on Apache — Your server needs mod_rewrite enabled for pretty permalinks to work. Some cheap hosts disable it by default.
  4. Nginx missing rewrite rules — If you’re on Nginx, there’s no .htaccess. The rewrite rules live in your server block config, and they’re often missing after a migration.
  5. Custom post type rewrite flush needed — If a plugin registers a custom post type and the rewrite rules haven’t been flushed, those URLs 404 immediately.

How to Fix It

This fixes the problem about 70% of the time. Go to Settings → Permalinks in your WordPress admin. Don’t change anything — just click Save Changes. This forces WordPress to regenerate its rewrite rules.

If you can’t access the admin, use WP-CLI over SSH:

wp rewrite flush

Check your site. If posts load now, you’re done. If not, keep going.

Step 2: Check and Reset .htaccess

Connect to your site via FTP or SSH and open the .htaccess file in your WordPress root directory (same level as wp-config.php).

The file should contain this block for a standard WordPress install:

# BEGIN WordPress
<IfModule mod_rewrite.c>
RewriteEngine On
RewriteBase /
RewriteRule ^index\.php$ - [L]
RewriteCond %{REQUEST_FILENAME} !-f
RewriteCond %{REQUEST_FILENAME} !-d
RewriteRule. /index.php [L]
</IfModule>
# END WordPress

If the file is empty, missing, or full of garbage, replace its contents with the block above. If the file doesn’t exist, create it. Then set permissions:

chmod 644.htaccess

If WordPress can’t write to .htaccess (you’ll see a notice in the Permalinks screen), temporarily set chmod 666, save permalinks, then set it back to 644.

Step 3: Verify mod_rewrite Is Enabled

SSH into your server and check:

apache2ctl -M | grep rewrite

You should see rewrite_module. If not, enable it:

sudo a2enmod rewrite
sudo systemctl restart apache2

On Nginx, there’s no mod_rewrite. Instead, confirm your server block includes the WordPress rewrite rule:

location / {
 try_files $uri $uri/ /index.php?$args;
}

Reload Nginx after any changes:

sudo nginx -t && sudo systemctl reload nginx

Step 4: Enable Debug Mode to Check for Plugin Conflicts

If flushing rewrites didn’t help, a plugin might be interfering with URL routing. Add this to wp-config.php (before the “stop editing” comment):

define( 'WP_DEBUG', true );
define( 'WP_DEBUG_LOG', true );
define( 'WP_DEBUG_DISPLAY', false );

Then deactivate all plugins at once:

wp plugin deactivate --all

Check your site. If the 404s are gone, reactivate plugins one by one to find the culprit:

wp plugin activate plugin-name

Test after each activation. The plugin that brings back the 404 is your problem. Update it, replace it, or contact the developer.

Step 5: Check for Custom Post Type Rewrite Issues

If only custom post type URLs are 404ing (like /portfolio/ or /products/), the rewrite rules for that post type haven’t been registered. This happens after activating a new plugin or theme that registers custom post types.

Flush rewrites with the --hard flag:

wp rewrite flush --hard

This regenerates both the internal rewrite rules and the .htaccess file. If you’re building a custom plugin that registers post types, skip this if you want headaches later — always hook flush_rewrite_rules on plugin activation:

register_activation_hook( __FILE__, function() {
 your_register_post_types_function();
 flush_rewrite_rules();
});

Step 6: Check Your WordPress Address and Site Address

Go to Settings → General (or check wp-config.php) and make sure WordPress Address (URL) and Site Address (URL) match and use the correct protocol. A mismatch between http and https or www and non-www causes routing failures.

You can force these in wp-config.php:

define( 'WP_HOME', 'https://yourdomain.com' );
define( 'WP_SITEURL', 'https://yourdomain.com' );

Prevention

  • Never manually edit .htaccess unless you know exactly what you’re adding. Always back it up first.
  • Flush permalinks after any plugin or theme change that registers custom post types or taxonomies. A quick trip to Settings → Permalinks → Save costs you five seconds and prevents hours of debugging.
  • Use WP-CLI in your deployment workflow. Add wp rewrite flush to your deploy script so rewrites regenerate automatically after every release.
  • Keep a backup of your working .htaccess in version control or your server backup system. When things break, you can restore it in seconds instead of troubleshooting from scratch.

Last verified: April 2026