1

My website is using Cloudflare in order to enable SSL (free SSL is not available on my host, Hostgator). Everything seems to be working fine, except when I return a 404 page. That results in

This site can’t be reached

The webpage at https://example.com/example-url might be temporarily down or it may have moved permanently to a new web address.

ERR_INVALID_RESPONSE

If I send a HTTP 200 response code instead of 404, everything works as normal - even for the same URL. I also tried sending HTTP 500, and that works fine too! So it's definitely something about the 404 response code that's causing the problem.

The reason I believe the problem has to do with Cloudflare is that

  1. It works fine on my local development environment (not using SSL).
  2. If I run curl https://example.com/example-url I get the correct 404 page back, and the HTTP status is 404 as expected.

I have other sites using Cloudflare as well, but they don't seem to have any problems returning a 404 response, which makes me think it's some configuration problem on Cloudflare for this one site.

Any ideas?

  • Why even use a host that doesn't offer security for its customers? If you can't install your own SSL with your web host then you with the wrong web host. Using Cloudflare SSL without an origin SSL does not protect your customers, its false security since the traffic between you and Cloudflare is not encrypted... go the distance and ditch naff website hosts. – Simon Hayter Sep 2 '18 at 21:04
  • @SimonHayter The websites I'm hosting do not and will not handle any sensitive user data, so there's no "false sense of security" since there is nothing to secure. Moving all my domains, CRON-jobs, etc. to another host and getting used to their interface (if other than CPanel) would be a pain in the ass and just not worth the trouble. Hopefully Hostgator will come around, until then I'll let these existing sites stay as is. That said, I probably wouldn't go with Hostgator today if I was about to choose a host. But since I have already prepaid a few years hosting, it's a different story. – Magnus W Sep 11 '18 at 9:01
1

It turns out that the problem was how I was generating the response headers.

I'm using the Slim PHP framework, and a custom error handler middleware. It looked like this:

class ErrorResponseHandler {

    protected $view = null;

    function __construct(\Slim\Views\Twig $view) {
        $this->view = $view;
    }


    public function __invoke(Request $request, Response $response, $next) {
        $response = $next($request, $response);

        if (404 === $response->getStatusCode() ) {
            // Pass an empty response to the 404-handler in MainController
            return (new MainController($this->view))->notFound404($request, new Response());
        }

        // Any other request, pass on current response
        return $response;
    }

}

I'm creating a new Response object in order to get an empty body without the default 404 HTML generated by Slim. However, creating a new Response object will apparently set the Content-Type header to application/x-httpd-php5, which is not understood by browsers (I should have seen this when using curl --head, but I missed it).

The solution is to set the correct Content-Type header, like this:

    if (404 === $response->getStatusCode() ) {
        // Pass an empty response to the 404-handler in MainController
        $new_response = (new Response())->withHeader('Content-Type', 'text/html');
        return (new MainController($this->view))->notFound404($request, $new_response);
    }

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.