Search code examples
php.htaccessnginxpleskcustom-error-pages

custom error page is not working with .htaccess or Apache & nginx Settings


I have created a 404 page for my project and for the life of me I can't seem to get it to work. when going to a non URL I get a white page with "File not found".

www.example.com/wrongurl i get a white page file not found

www.example.com/wrongurl.php i get a white page file not found

www.example.com/wrongurl.html i get my custom 404 page

I have tried both .htaccess file and the Apache & nginx Settings via my Plesk panel

My .htaccess file

Options -MultiViews
RewriteEngine On
RewriteCond %{ENV:REDIRECT_STATUS} 200
RewriteRule ^ - [L]

# Append trailing slash if omitted (canonical redirect)
RewriteRule ^news$ /$0/ [R=301,L]

RewriteCond %{QUERY_STRING} (?:^|&)article_slug=([\w-]*)(?:$|&)
RewriteRule ^news\.php$ /news/%1 [R=301,L]

RewriteRule ^news/([\w-]*)$ /news.php?article_slug=$1 [QSA,L]
RewriteCond %{REQUEST_FILENAME} !-f
RewriteRule ^([^\.]+)$ $1.php [NC,L]
ErrorDocument 404 /404.php

Apache & nginx Settings enter image description here

To troubleshoot the issue I have done the following

  1. Checked that my .htaccess file is being processed properly. I added an invalid line to it, (foo bar), and tried to access a non-existent page. and I got the Internal Server Error instead of "File not found".

  2. I have Checked that my custom error page is located in the correct directory and has the correct permissions. And I can access my error page directly by typing the URL into my browser to see if it loads.

  3. My Apache configuration allows custom error pages.

  4. I have tried to use the absolute path for my ErrorDocument directive. Instead of using a relative path like ErrorDocument 404 /404.php, I have tried using the absolute path like ErrorDocument 404 /var/www/html/404.php

Any help on this would be much appreciated.


Solution

  • This is likely to do with how PHP is installed on your server. Any URL with a .php extension is likely proxied (using Nginx? You mention both Nginx and Apache) to the PHP executable, completely bypassing Apache/.htaccess.

    When you request a URL of the form /wrongurl then your last rule is internally rewriting this to /wrongurl.php and it's this that is generating the "white page file not found" response.

    You can at least prevent /wrongurl from being rewritten to /wrongurl.php and bypassing your custom 404 by first checking that the target file exists before rewriting the request. In other words, change the last rule from this:

    RewriteCond %{REQUEST_FILENAME} !-f
    RewriteRule ^([^\.]+)$ $1.php [NC,L]
    

    to this:

    RewriteCond %{DOCUMENT_ROOT}/$1.php -f
    RewriteRule ^([^.]+)$ $1.php [L]
    

    So, instead of rewriting the request when the requested URL does not map to a file. Only rewrite the request when the corresponding .php file exists.

    No need to backslash-escape literal dots inside a regex character class. And no need for the NC flag on that rule either.