Support » Fixing WordPress » Theme’s 404.php is being loaded “behind the scenes”

  • So after a lot of debugging I’ve found this to be the situation.

    My theme’s 404.php has an error_log print on it. I see it keeps being called every page load, sometimes numerous times. Even though the pages are loading fine.

    I eventually found it to be because, in the HTML, there are broken images. (Test encironment, the images don’t exist on the server.)

    For some reason, each time the page “encounters” one of these, the entire 404.php template – which means the theme’s header, sidebars, widgets, etc – are all processed and “rendered” – just not visually.

    This has to do with .htaccess.
    If I delete the standard .htaccess file, this does not occur. If I re-save permalinks to post-name, my pages work again but this 404 issue keeps happening.

    How to resolve this?

    • This topic was modified 6 months, 2 weeks ago by Jan Dembowski. Reason: Moved to Fixing WordPress, this is not an Developing with WordPress topic
Viewing 15 replies - 1 through 15 (of 18 total)
  • I don’t see how it could be otherwise. The .htaccess file says that if the file exists, serve it, otherwise let WordPress handle it.

    @joyously I’m honestly not sure and just asking, but is this the desired behavior? If you have a user-written post and they embed an image in it that doesn’t exist, the theme’s 404.php should execute (but not display) on the loading of that post on the front end because it encountered a “broken image”?

    I guess what I’m asking is, WHERE is it determined by WordPress to fetch a theme’s 404 page?

    @ftlralph

    As per WordPress template hierarchy, 404 template is used when the WordPress determines that the current page is not found.
    Here’s more on template hierarchy:
    https://wphierarchy.com/

    Now, as you mentioned, the pages are still being rendered, apparently, something either in theme’s functions.php or some plugin, is manipulating the default behavior of the WordPress which determines when a URL is 404. In this case, these plugins might help you determine the cause:
    https://wordpress.org/plugins/query-monitor/
    https://wordpress.org/plugins/show-current-template/

    Also one more thing you mentioned about removing .htaccess file, can you please tell, when you remove that, do WordPress 404 page appears or does the web server’s(Apache’s) error page appear?

    The standard “WordPress” blob in .htaccess looks like this:

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

    The function of this is:
    1. If the requested URL is for /index.php, then load WordPress.
    2. Otherwise, if the requested URL matches an existing directory or file, then serve that asset.
    3. If no match above, then serve /index.php (which in the next round is caught by rule number 1.

    Nothing would stop you from writing a couple of lines above:
    Something like: If requested file extension is jpg, jpeg, pdf, txt, gif or … then just try to serve that file and look no further. This should speed up things, since 404 then will be served directly from Apache, without loading PHP, loading WordPress, etc.

    I’m too busy to figure out that magic line right now, though.

    You could try to add something like:
    RewriteCond %{REQUEST_URI} !\.(jpg|png|gif|jpeg|txt|css|js|php)$
    on the line before RewriteCond %{REQUEST_FILENAME} !-f

    This means that if the request URL ends on .jpg, .png, etc. then no rewrite will happen.
    I found my inspiration here: https://stackoverflow.com/questions/4038079/rewriterule-in-htaccess-to-match-certain-file-extensions

    @gagan0123 Thanks for the reply

    I’ve been using the Query Monitor plugin, didn’t see anything helpful. But I just installed the Template one, still nothing of interest?
    This is loading index.php / homepage:

    https://i.imgur.com/zH8Dt37.png

    There is 1 broken image on the page, the Console shows this:

    https://i.imgur.com/O14sgLH.png

    But the page loads fine. Meanwhile in my error_log, I have the theme’s 404.php printing out “hello” aka the template is being tapped to run.

    Removing the .htaccess file shows the normal Apache 404 “not found” page.

    @tobifjellner I appreciate the help. I might have to resort to this, but this isn’t actually fixing the underlying condition. Right? Again I assume this “loading the 404 template behind the scenes on every broken image found in a page”-thing isn’t supposed to actually be a thing.

    Normally your theme and plugins should only request resources that are in place.

    @ftlralph

    Hey, I’m not an Apache fan, and in the Nginx configs I use, I do handle this situation for WordPress sites, and Nginx handles 404 for static resources, not forwarding those requests to PHP, so I thought, there must be something similar in Apache as well, and I found one solution, RewriteCond, before WordPress’ conditions, that make sure that static resources are served from Apache only.

    Here’s complete .htaccess file that you can try

    
    # Begin Custom Static Handler
    <IfModule mod_rewrite.c> 
    RewriteEngine On 
    RewriteCond %{REQUEST_FILENAME} !-f 
    RewriteCond %{REQUEST_FILENAME} !-d 
    RewriteCond %{REQUEST_URI} !(robots\.txt|[a-z0-9_\-]*sitemap[a-z0-9_\-]*\.(xml|xsl|html)(\.gz)?) 
    RewriteCond %{REQUEST_URI} \.(css|htc|less|js|js2|js3|js4|html|htm|rtf|rtx|svg|txt|xsd|xsl|xml|asf|asx|wax|wmv|wmx|avi|bmp|class|divx|doc|docx|eot|exe|gif|gz|gzip|ico|jpg|jpeg|jpe|webp|json|mdb|mid|midi|mov|qt|mp3|m4a|mp4|m4v|mpeg|mpg|mpe|mpp|otf|_otf|odb|odc|odf|odg|odp|ods|odt|ogg|pdf|png|pot|pps|ppt|pptx|ra|ram|svg|svgz|swf|tar|tif|tiff|ttf|ttc|_ttf|wav|wma|wri|woff|woff2|xla|xls|xlsx|xlt|xlw|zip)$ [NC] 
    RewriteRule .* - [L] 
    </IfModule>
    # End Custom Static Handler
    # 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
    

    Tried it in a virtual docker container, and appears to be working, let me know if this works out for you as well.

    @tobifjellner this happens when posts/comments contain broken images, user-content

    if the html has a “dead image”, the 404.php theme file is run but not displayed

    so what I’m asking here basically is, this isn’t normal behavior right? Where is WP determining to fetch the theme’s 404 file, so I can maybe fix this?

    @gagan0123 thanks even though I still do not want to hack at the htaccess (unless every WP installation needs this “fix” which I doubt) I tried it but still getting the theme’s 404.php file running if a broken img is encountered-

    @ftlralph

    I tested out the .htaccess code using default WordPress theme, twentytwenty, with 404.php edited to log to error log.

    Here’s the screencast of my findings:

    As you can see, without that custom section, the 404 template is rendered, but with that custom section, the 404 template is not rendered.

    So it works as it should, at least with default Apache setup, that honors .htaccess file, and the rules defined in it. Maybe something else is in play, on your server.

    To confirm if the template would be rendered or not, simply open any non existent image file from your site, as I did in the end of the screencast.

    @gagan0123 thanks for taking the time to help

    okay so I tried the htaccess on my live site now vs just a local test site

    it’s tough to tell if it’s working, because the site is live with many users, there are still occasional logging of the 404 page being accessed but I *think* less than it would be otherwise?

    is there a way to also have the 404.php error_log out what exactly is being requested, filename or something, because having that in the log would help identify if these are valid 404’s or what

    @ftlralph

    Don’t add that much info in 404.php file, instead, if you access a non existing jpg file URL for instance
    https://example.com/this-image-does-not-exist.jpg

    and get Apache’s 404, then the htaccess I shared, is working, if you get WordPress 404 page, then its not, its as simple as that 🙂

    @gagan0123 I’ll check this later when I can, and thank you, but point is the 404.php is still logging a lot – more than “normal” I would say.

    So something *else* is going on, and that’s why I’m just wondering if you or anyone else would know how to actually retrive what call to what file/directory it is that’s triggering a specific call to the 404.php page

Viewing 15 replies - 1 through 15 (of 18 total)
  • The topic ‘Theme’s 404.php is being loaded “behind the scenes”’ is closed to new replies.