2026年11月12日
2026年11月12日
Fix WordPress Permalink 404 Errors on Apache
This article is a localized edition of the Japanese original. Read the Japanese original
Introduction
You switch the WordPress permalink setting from "Plain" to something like "Post name," and suddenly the front page still loads but every single post returns a 404. This is a classic problem on Apache. Almost every time, the cause is that mod_rewrite is disabled, or that the server is configured so that .htaccess is never read.
This article assumes an Apache 2.4 + WordPress setup and walks through how to isolate the cause of the 404 errors and fix it. We cover, in order, a2enmod rewrite, the AllowOverride setting inside the VirtualHost, regenerating .htaccess, and what to watch out for on SELinux systems.
Because subdirectory and subdomain installs are also touched on, the same approach applies to WordPress setups that run multiple sites.
Symptoms and Background
- The front page
/loads, but/sample-post/returns a 404 - Saving the settings under "Permalinks" in the admin does not help
.htaccessis missing from/var/www/htmlor cannot be written- Only the URLs of a custom post type return 404
Steps and Configuration
Step 1: Check That mod_rewrite Is Enabled
First, confirm that the rewrite module is enabled in Apache.
# Debian/Ubuntu: enable the module
sudo a2enmod rewrite
# List the enabled modules
apache2ctl -M | grep rewrite
# RHEL family: check whether /etc/httpd/conf.modules.d/00-base.conf contains the line below
grep rewrite /etc/httpd/conf.modules.d/00-base.conf
# Apply the settings
sudo systemctl restart apache2 # Debian family
# sudo systemctl restart httpd # RHEL family
Step 2: Allow AllowOverride
Adjust the VirtualHost configuration so that .htaccess is read.
# Open the VirtualHost configuration
sudo nano /etc/apache2/sites-available/wordpress.conf
# Set the Directory block as follows
# <Directory /var/www/html>
# AllowOverride All
# Require all granted
# </Directory>
# Check the syntax
sudo apache2ctl configtest
# Apply
sudo systemctl reload apache2
Step 3: Regenerate .htaccess
Write the standard WordPress rewrite rules.
# Create .htaccess if it doesn't exist
sudo touch /var/www/html/.htaccess
sudo chown www-data:www-data /var/www/html/.htaccess
sudo chmod 644 /var/www/html/.htaccess
# Write the standard WordPress rewrite rules
sudo tee /var/www/html/.htaccess > /dev/null <<'EOF'
# 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
EOF
Step 4: Re-save the Permalinks in the Admin
As the final step, re-save the permalinks and clear the cache.
# If wp-cli is installed, regenerate with a command
sudo -u www-data wp rewrite flush --hard --path=/var/www/html
# Set the permalink structure to Post name
sudo -u www-data wp rewrite structure '/%postname%/' --path=/var/www/html
# Check the permalink status
sudo -u www-data wp rewrite list --path=/var/www/html
# Check while bypassing the browser cache
curl -I https://example.com/sample-post/
Caveats
- With
AllowOverride None,.htaccessis never read at all, soa2enmod rewritealone is not enough - If
.htaccessis not available on a shared hosting plan, you need to enable the mod_rewrite equivalent from the hosting provider's control panel - On systems with SELinux enabled, writes are denied unless you set the label of
.htaccesstohttpd_sys_rw_content_t - When you change permalinks, also plan for redirects (a Redirect 301 from the old URLs)
Summary
1. Enable mod_rewrite: a2enmod rewrite + an Apache restart is the baseline requirement
2. AllowOverride All: explicitly allow it in the VirtualHost's Directory block
3. Regenerate .htaccess: write the standard WordPress rules and set the owner to www-data
4. Force a flush with wp-cli: if you cannot open the admin, use wp rewrite flush --hard
5. If 404s remain: suspect SELinux, file permissions, or the subdirectory setup
Related articles:
- Setting Content-Type and charset in Apache
- Fixing an HTTPS Redirect Loop in Apache
- Hardening WordPress Security with .htaccess
Questions about WordPress? The publisher of this site is based in Japan and replies in Japanese. Contact (Japanese)