How to Fix WordPress Permalink 404 Errors on cPanel and IIS
In this article8 sections
You change the permalink structure in WordPress, click Save, and suddenly every page except the home page returns a 404 Not Found. The posts still exist in the dashboard. The problem is the web server, which no longer knows how to hand a pretty address such as /my-first-post/ to WordPress. This guide explains why it happens on cPanel and on IIS, the fix for each, and how to confirm that the links work before you close the browser.
If your site runs on SiteHarbour’s WordPress hosting, the server rewrite rules are already in place, so a 404 there usually means a plugin or a manual edit has changed them. The steps below show how to check that, and how to repair it by hand.
Why permalinks break
WordPress has two ways to serve a page. A plain address such as ?p=123 works with no help from the server. A pretty address such as /sample-post/ does not match any file or folder, so the web server must rewrite it to index.php and let WordPress look up the post. That rewrite is written in .htaccess on Apache and LiteSpeed, and in a rewrite section of web.config on IIS. When the rewrite is missing, damaged or not read, the pretty addresses fail.
Step 1: Confirm it is a rewrite problem
Open the home page, then open one post using its plain address. In a browser, change the post URL to https://example.com/?p=1, using a real post ID from the dashboard. If that address loads, WordPress works, and only the rewrite is broken. If it also returns 404, the problem is elsewhere, such as the theme or the database, which is a different fault.
Check the permalink setting in the dashboard under Settings > Permalinks. Note the structure, then select Save Changes without changing anything. WordPress tries to write the rewrite rules again, and that alone fixes many cases.
Step 2: Fix the .htaccess file on cPanel
On an Apache or LiteSpeed server, WordPress writes a block between two markers in .htaccess. Open the file in File Manager, with hidden files shown, and look for these lines:
# 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
If the block is missing, add it above any other rules, or save the permalink settings again so WordPress writes it. If the file is empty or unreadable, check its permissions: a file the web server cannot read is ignored, so the rewrite never runs. Set it to 644.
Check the result from a terminal:
curl -sI https://example.com/sample-post/ | head -n 1
Expected: HTTP/2 200 for a real post. If the request still returns 404 after the block is correct, check whether the domain’s PHP handler is set up correctly, as described in how to choose the right PHP version and handler in cPanel.
Step 3: Fix the web.config file on IIS
On Windows hosting, IIS needs a rewrite rule in web.config. A WordPress site on IIS needs this rule, so add it inside the system.webServer element, in a rewrite section:
<rewrite>
<rules>
<rule name="WordPress" stopProcessing="true">
<match url="^(.*)$" ignoreCase="false" />
<conditions logicalGrouping="MatchAll">
<add input="{REQUEST_FILENAME}" matchType="IsFile" ignoreCase="false" negate="true" />
<add input="{REQUEST_FILENAME}" matchType="IsDirectory" ignoreCase="false" negate="true" />
</conditions>
<action type="Rewrite" url="index.php" />
</rule>
</rules>
</rewrite>
The rule sends any address that is not a real file or folder to index.php, which is what WordPress needs. Keep a copy of the file before you edit it, because a syntax error in web.config stops the whole site. The rewrite module must be installed, which is standard on SiteHarbour’s Windows plans. The same file is covered in how to redirect HTTP to HTTPS on IIS, and the two rules can sit side by side.
Step 4: Check the rest of the site
After the rewrite works, check a page of each type: a post, a category archive, a page, the search results and a custom post type if you use one. Each type has its own address pattern, and a rule that works for posts can still miss archives. Use the same curl check on each one.
Step 5: Stop it happening again
Most repeat cases come from a plugin that writes its own rules, or from a manual edit to .htaccess that removes the WordPress block. Keep any custom rules outside the WordPress block, and check the file after you install or remove a plugin that is known to change rewrites, such as a security or redirect plugin.
Common mistakes
- Editing above the WordPress block without care. A rule above it can catch every request before WordPress sees it.
- Trusting the dashboard. The dashboard runs on the same rewrite. Test the public address, not only the admin screen.
- Setting the file to 777. That is not the fix, and it exposes the site.
- Saving permalinks on IIS and expecting a rule. IIS does not read
.htaccess, so the web.config rule is needed.
Frequently asked questions
Is the home page working while posts show 404?
Yes, that is the usual sign. The home page is a request to /, which the server handles without the rewrite. Any other address needs the rewrite.
Can I use plain permalinks instead?
Yes, it avoids the rewrite entirely. It is a poor choice for search, because the address does not describe the page, so use it only as a temporary test.
Why did this start after an update?
An update can rewrite .htaccess or change a plugin’s rules. Compare the file with the block in Step 2 after each update.
Do I need to restart the server?
No. Apache, LiteSpeed and IIS read the rewrite rules on the next request, so a saved file takes effect at once.
A permalink 404 is a rewrite problem, and it has one of two fixes: the WordPress block in .htaccess on cPanel, or a rewrite rule in web.config on IIS. Test a plain address to confirm, save the permalinks once, and then check every page type. For the wider set of WordPress security settings that go with a clean setup, read how to secure WordPress on cPanel hosting.