Troubleshooting
404 errors on static files slow down browsing
When you visit an address that does not exist in WordPress, it returns a "page not found" 404 error with your own theme's design, which makes sense because it keeps a familiar browsing flow for the visitor.
The problem can arise when a page calls an image, CSS or JavaScript file that does not exist and the server configuration also sends that request to WordPress. It does not happen on every server: first confirm which process generates the 404 response.
It is worth understanding the difference in cost. In a configuration that serves static resources directly, an existing file does not need to start PHP; the real time depends on the server and the network. A file that does not exist falls through to WordPress routing, which boots the whole application, loads the plugins, queries the database and builds your theme's 404 page. In a real case measured on our servers, each of those 404s returned 28 KB of rendered page, while the same error served by the web server took 796 bytes.
If the 404 template itself requests the missing resource again, each error can generate additional requests. To link them to an overload, check that they match the increase in processes or response time in both time and path.
How to detect it
High CPU usage and several PHP processes on index.php are signs, not the confirmed cause. To check the relationship, review the access log in cPanel from Metrics → Raw Access.
Look in it for the same URL repeated many times. Example based on the case, with a documentation address and domain:
192.0.2.10 - - [09/Aug/2026:22:36:03 +0200] "GET /wp-content/plugins/popup-maker/dist/packages/block-library-style.css?ver=7424eb959f91acb8bbb2 HTTP/1.1" 404 28113 "-" "WordPress/6.8.7; https://www.midominio.com"
Two details give the problem away:
- The IP matches the server's and the user agent declares WordPress. In that specific case it was an internal request; in another log you need to check both details before stating it.
- The code is 404 and the size was tens of kilobytes. That measurement was consistent with the page rendered by the theme, but you should check your own response.
In that specific case the website was requesting the same non-existent CSS from itself about six times a minute, non-stop for weeks, and ended up exhausting the account's CPU limit.
The solution: do not let WordPress handle those 404s
The main solution is to remove the reference to the non-existent content. If you have confirmed that those requests reach WordPress, the following rule acts as a safety net and makes the server respond earlier for the listed extensions.
Before changing it, download a copy of the current .htaccess so you can restore it if the website returns a 500 error. To stop WordPress handling 404 errors for static files, then add the following block:
# BEGIN 404 ESTATICOS <IfModule mod_rewrite.c> RewriteEngine On RewriteCond %{REQUEST_FILENAME} !-f RewriteCond %{REQUEST_FILENAME} !-d RewriteCond %{REQUEST_URI} \.(gif|jpe?g|png|webp|avif|svg|ico|css|js|map|woff2?|ttf|eot)$ [NC] RewriteRule ^ - [R=404,L] </IfModule> # END 404 ESTATICOS
The first two conditions let through any file or directory that does exist, so it only acts on what is missing. The third limits the rule to static content extensions and usually leaves out website addresses without an extension. It is worth including fonts (woff, woff2, ttf, eot) and source maps (map), which are among the biggest sources of silent 404s in a theme.
Where to place the block
Find the # BEGIN WordPress line in the file and paste the block just above it. Keep it outside any block that a plugin manages automatically.
The reason it goes above # BEGIN WordPress is that this block is precisely the one that sends everything that does not exist on disk to index.php. If you put it after, WordPress will already have taken the request.
Do not place it before the LiteSpeed Cache rules: you could intercept a URL the plugin needs to rewrite. As blocks vary by installation, test an existing optimised image and a made-up URL before keeping the change.
Also check that ErrorDocument 404 does not point to PHP. If you use ErrorDocument 404 /404.shtml, check that the file exists, is static and does not go back through WordPress.
Check that it works
After saving the file, open these three addresses in your browser, replacing midominio.com with your own.
1. Your website, to rule out a typo
https://midominio.com/
It should load normally. If a 500 or a blank screen appears right after the change, restore the copy and check the log. There may be a typo, a disallowed directive or an interaction with other rules; the code alone does not tell you which.
2. A static file that does not exist, with a made-up name
https://midominio.com/esto-no-existe.css
It should respond with a 404 code and a lightweight page served without loading the WordPress design. Its exact appearance depends on the server configuration and ErrorDocument.
If instead you see the "not found" page with your theme's design, menu and footer, check the order of the rule and ErrorDocument: the latter may be sending the error back to PHP.
3. A page on your website that does not exist
https://midominio.com/esta-pagina-no-existe/
Here you should still see your theme's 404, with its usual design. The rule only intercepts non-existent addresses ending in one of the listed extensions. If your application uses virtual routes with those extensions, add a specific exclusion and test them before keeping the rule.
This is a safety net, not the fix
The block makes the error cheaper, but the call to the missing file keeps happening. Find the source with the Network tab of the browser's developer tools, which tells you which resource is being requested and from where.
The Initiator tab and the log let you find out which page or component requested the resource. Reinstall a plugin only if you have confirmed that the file should belong to that package; if the reference comes from a cache, purge that cache after fixing it.
If you want to go deeper into your installation's performance, see the WordPress optimisation guide and the LiteSpeed Cache guide.
When testing a non-existent URL, also use query parameters and upper case in the extension. Check any virtual endpoint ending in .js, .css or another listed extension before deploying: the rule cannot tell it apart from a missing file. Compare the HTTP code and the load before and after, keeping the fix to the reference as the main task.
You may also find useful
- Debug errors in WordPress Find WordPress blank screens and internal failures by sending WP_DEBUG to a private log, without sho...
- Diagnose "Missed schedule" Check why a scheduled post was not published before replacing WP-Cron with a server task.
- Diagnose Sodium cryptographic errors in WordPress Tell a missing Sodium extension apart from an invalid argument in sodium_compat before changing the...
- Elementor 3.6.x, historical compatibility issues Historical guide to diagnosing errors that appeared after updating to Elementor 3.6 without attribut...
Something wrong or out of date? Tell us and we will review it.