I have a site whose .htaccess file contains:

ErrorDocument 404 /errors/404.html
ErrorDocument 500 /errors/500.html

The 404 redirect works just fine, but when I encounter a 500 Internal Server Error, it gives the default Internal Server Error message as opposed to /errors/500.html. It also says

Additionally, a 500 Internal Server Error error was encountered while trying to use an ErrorDocument to handle the request.

More info: I can get it to throw 500 if I type a trailing slash on a .html page that has had the ".html" removed by the remaining part of the htaccess file (e.g. if I try to navigate to http://example.com/test/ where test is actually test.html, then I get an internal server error):

#example.com/page will display the contents of example.com/page.html
RewriteCond %{REQUEST_FILENAME} !-f
RewriteCond %{REQUEST_FILENAME} !-d
RewriteCond %{REQUEST_FILENAME}.html -f
RewriteRule ^(.+)$ $1.html [L,QSA]

#302 from example.com/page.html to example.com/page
RewriteCond %{THE_REQUEST} ^[A-Z]{3,9}\ /.*\.html\ HTTP/
RewriteRule ^(.*)\.html$ /$1 [R=302,L]
  • just a guess: file permissions of the error files differ; or the ".html"-rewrite rule is conflicting with a "real" site you have that has the URL-key 500 Oct 5 '15 at 20:10
  • Two questions: 1. Can you visit the 500.html page manually? This will show its its a permission error. 2. How are you simulating the 500 error? I've no idea what you mean by yours last sentence "I can get it to throw 500 if I type a trailing slash...etc. especially since you then give examples with no trailing slashes. Oct 6 '15 at 22:06
  • @BazzaDP I can visit the 500.html page manually. Woops, I'll update the example to have a trailing slash. So if example.com/test/ is tried, a trailing slash is on the end of what is actually a html file
    – binaryfunt
    Oct 7 '15 at 20:28
  • You still aren't explaining yourself very well. So you can visit example.com/errors/500.html in a browser and see the error page? I don't see how that would work given the second RewriteRule so doubt that is the case. And I've still no idea what you are on about with your test examples. Please explain exactly what you are doing, what is happening, and what you expect to happen. I suspect it's a problem with those rewrite rules so I would comment them all out and then try and see if it works. But that still comes back to the question "how are you creating a 500 error to test this?". Oct 7 '15 at 21:03
  • @BazzaDP If I navigate to example.com/errors/500.html it gets rewritten as example.com/errors/500 and indeed shows my custom error page. If I navigate to example.com/test, it shows the page test.html. If I try to navigate to example.com/test/, or example.com/test/foo I get the Apache internal server error message. (There is no directory called test). I would expect to see the custom 500 page, considering that's what I set in my ErrorDocument rule in htaccess
    – binaryfunt
    Oct 7 '15 at 21:27

I would try two things -

  1. Check permissions of 500.html (try setting it to 777 to be very sure - modify it later).

  2. Try 500.htm (or 500.txt) instead of 500.html (just to be sure that your other rules in htaccess are not messing up with the ErrorDocument 500.html page). Also, remember to change the htaccess ErrorDocument rule to 500.htm (or 500.txt).

Also, as per http://httpd.apache.org/docs/2.4/mod/core.html#errordocument

Although most error messages can be overridden, there are certain circumstances where the internal messages are used regardless of the setting of ErrorDocument. In particular, if a malformed request is detected, normal request processing will be immediately halted and the internal error message returned. This is necessary to guard against security problems caused by bad requests.

Try some other ways to simulate 500 error.

  • Forgive me, but how can I check permissions of 500.html? According to Microsoft, 777 is The connection attempt failed because the modem or other connecting device on the remote computer is out of order. How would I be able to get a 777 error nowadays?
    – binaryfunt
    Oct 7 '15 at 20:34
  • 1
    If you can visit the page manually, as per your reply to my comment, then it's not a permission error. Oct 7 '15 at 20:48
  • I meant permission of the file be set to 777 (readable, writable and executable by everyone) in linux.
    – Aakash
    Oct 7 '15 at 21:35
  • Ah. But I think it's the malformed request that happens as a result of the rewrite loop (mentioned by w3d)
    – binaryfunt
    Oct 7 '15 at 22:29

but when I encounter a 500 Internal Server Error, it gives the default Internal Server Error

The problem is that custom 500 error documents simply don't get triggered for errors in .htaccess - which is what's happening here. As Aakash has already quoted, this may come under the realm of a "malformed request". If you check your error log it should state: "core:error".

In fact it is a bit tricky to simulate a real error that will trigger the custom 500 error document.

However, you can manually trigger a 500 error, which will call your custom error handler with something like the following:

RewriteRule ^ - [R=500]

Additionally, a 500 Internal Server Error error was encountered while trying to use an ErrorDocument to handle the request.

Admittedly, the wording of this is a bit confusing. However, all system generated 500 errors appear to contain this same text. I think it just means that it couldn't "handle the request"... there was no ErrorDocument to handle the request, so here's a catch-all 500 Internal Server Error. Which is all that a 500 error really is... an undefined error state, because nothing else fits (check your server error log for details).

More info: I can get it to throw 500 if I type a trailing slash on a .html page that has had the ".html" removed...

Not sure that this is really part of your question, but this 500 error is the result of a rewrite loop. Specifically:

RewriteCond %{REQUEST_FILENAME}.html -f
RewriteRule ^(.+)$ $1.html [L,QSA]

Request: http://example.com/test/ (with the extra slash)

In this case the %{REQUEST_FILENAME} is /path/to/test (no trailing slash), so the condition %{REQUEST_FILENAME}.html -f is true (/path/to/test.html does exist).

However, the URL-path that is captured by the RewriteRule pattern does contain the trailing slash ie. test/ - it is not the same as the REQUEST_FILENAME in this instance. So the URL gets incorrectly rewritten to test/.html.

And the rewriting starts over again from the top (because the URL has changed)... test/.html.html, test/.html.html.html, etc. (Because the REQUEST_FILENAME is always /path/to/test.)

  • I thought the same as you initially, but the rewrite is an internal rewrite so does not get returned to the client as a 301 nor should Apache apply the rewrite rule again (as L is set), and even if it did, the condition stating the "%{REQUEST_FILENAME}.html -f" exists would fail as it would look for .html.html the second time rather than test.html. Though I think you're probably on the right track anyway. Oct 7 '15 at 20:57
  • @BazzaDP Yes, it's an internal rewrite (I'm not sure of the relevance of whether it gets returned to the client or not?). The L flag simply stops the current round of processing (it doesn't stop all processing like the END flag). Since the URL has been rewritten/changed, the processing starts again from the top (because it is an internal rewrite). In this instance the value of REQUEST_FILENAME does not change because everything after /test is stripped (in fact, everything after the last matched directory + filename is stripped), so the same success condition is performed each time.
    – MrWhite
    Oct 7 '15 at 22:09
  • @BazzaDP I've run some tests on my own server and that is what appears to be happening.
    – MrWhite
    Oct 7 '15 at 22:10
  • 2
    Interesting. I didn't know that the processing starts again on a rewrite! I, incorrectly, thought you were assuming it was a 301 and so was leading to the client requesting it again and that was causing the loop. Surprised this doesn't lead to lots of rewrite loops - though I do see now that there is warning of this in the Apache docs. Very good Oct 7 '15 at 22:27

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.