I have a PHP file on my error subdomain (https://errors.example.com). And this is meant to serve as the error page for all subdomains. The format it goes through is https://errors.example.com?type=error?error=404 just an example but when I receive a 404 on a different sub. Or the main I get redirected to there. And that messes with the path that it shows... And it exposes where my error pages are...

My .htaccess file:

Options  +Indexes

Order deny,allow
<IfModule !mod_ssl.c>
Redirect permanent / https://www.example.com/
ErrorDocument 400 https://errors.example.com?type=error&error=400
ErrorDocument 401 https://errors.example.com?type=error&error=401
ErrorDocument 403 https://errors.example.com?type=error&error=403
ErrorDocument 404 https://errors.example.com?type=error&error=404
ErrorDocument 451 https://errors.example.com?type=error&error=451
ErrorDocument 500 https://errors.example.com?type=error&error=500

<IfModule mod_expires.c>
ExpiresActive On
ExpiresByType image/jpg "access 1 year"
ExpiresByType image/jpeg "access 1 year"
ExpiresByType image/gif "access 1 year"
ExpiresByType image/png "access 1 year"
ExpiresByType text/css "access 1 month"
ExpiresByType text/html "access 1 month"
ExpiresByType application/pdf "access 1 month"
ExpiresByType text/x-javascript "access 1 month"
ExpiresByType application/x-shockwave-flash "access 1 month"
ExpiresByType image/x-icon "access 1 year"
ExpiresDefault "access 1 month"
  • It is not possible to prevent a redirect under Apache when the error document is hosted on a different host name. – Stephen Ostermiller Mar 30 '17 at 15:15
ErrorDocument 400 https://errors.example.com?type=error&error=400

In order to prevent Apache triggering an external redirect to the error document you need to remove the absolute URL (scheme + hostname) and specify a root-relative filesystem path to your error document instead. By including an absolute URL, Apache implicitly triggers an external redirect (not desirable).

Basically, you can't get Apache to serve an error document via an internal subrequest that's on a different host.

If your main domain and all subdomains (including the errors subdomain) point to the same area on the filesystem then there shouldn't be a need to change hosts (ie. having a special errors subdomain is going to cause problems). The ErrorDocument URL is hidden from users anyway.

Another "problem" with the URL-path you've given is that you've not actually specified the error document filename (this becomes more obvious when you strip the scheme + hostname). I assume you are using the DirectoryIndex (eg. index.php)? But if you omit this then mod_dir will trigger another subrequest to the directory index.

So, try something like:

ErrorDocument 400 /index.php?type=error&error=400

Aside: If you are using PHP, then there is no real need to explicitly pass the HTTP status code to the error document (eg. &error=400). Providing the error document is triggered by an internal subrequest (as opposed to an external redirect, as mentioned above), then the HTTP status is available in the $_SERVER['REDIRECT_STATUS'] superglobal. This can also be used to determine whether the error document has been requested directly (REDIRECT_STATUS is not set in this instance). Although this may require a slight reworking of your PHP script.

ErrorDocument 400 /index.php?type=error
ErrorDocument 401 /index.php?type=error
ErrorDocument 403 /index.php?type=error

UPDATE: With regards to the use of $_SERVER['REDIRECT_STATUS'] and your error URL parameter... Note that (as mentioned above) REDIRECT_STATUS is not set on direct access. At other times it is set to the HTTP status code (a numeric string - the variable type is a string). It can also be set to "200" (OK) after a successful internal rewrite (this may or may not apply to your system, but it is worth checking for).

You should also assume that your error URL param might not be set. So, something like this in PHP:

// Get the HTTP status code...
// "error" URL param (if set) will override the REDIRECT_STATUS variable
$httpStatus = isset($_SERVER['REDIRECT_STATUS']) ? $_SERVER['REDIRECT_STATUS'] : null;
$httpStatus = isset($_GET['error']) ? $_GET['error'] : $httpStatus;

if (empty($httpStatus)) {
    // Direct access without the "error" parameter - abort?
    // Or force a 403 or 404 plus suitable response.
elseif ($httpStatus == '404') {
    // Process 404 error

// etc.

elseif ($httpStatus == '200') {
    // Not an error...
else {
    // Unknown error

This allows your error URL param to always override the REDIRECT_STATUS superglobal.

  • I forgot about that php server variable, I couldn't find it on google, thanks for answering another one of my questions @w3dk – Donovan_DMC Mar 30 '17 at 17:38
  • What would I need for a or in the php ex:if ($_SERVER['REDIRECT_STATUS'] === "404" or $_Get['error'] === "404")this is so I can trigger a error manually, for testing – Donovan_DMC Mar 30 '17 at 17:41
  • And what does $_SERVER['REDIRECT_STATUS'] return? Ex: 404 HTTP_404 etc... – Donovan_DMC Mar 30 '17 at 17:43
  • $_SERVER['REDIRECT_STATUS'] (if set) contains just the HTTP status code (as a string). I've updated my answer with some PHP example code and more explanation. – MrWhite Mar 30 '17 at 19:23

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.