5

Here is how my php-fpm config is:

location @site {
    fastcgi_pass   unix:/var/run/php5-fpm.sock;
    include fastcgi_params;
    fastcgi_param  SCRIPT_FILENAME $document_root/index.php;

    fastcgi_intercept_errors on;
    error_page 404 /404;
}

Because fastcgi_intercept_errors is enabled, when my PHP router returns a 404, Nginx will redirect to /404. Good.

But since /404 is generated by my PHP application, and my PHP application correctly sets a 404 response code, then Nginx will try to handle the error again! (which obviously ends in a loop)

Is there a solution to this?

Matthieu Napoli
  • 400
  • 1
  • 3
  • 11

2 Answers2

5

nginx is doing this because you told it to.

    fastcgi_intercept_errors on;

This means that nginx will not serve error responses generated by PHP, but have nginx handle them instead. Thus you get into your endless loop.

To resolve the problem, remove this directive (it defaults to off) or set it explicity to off.

Michael Hampton
  • 237,123
  • 42
  • 477
  • 940
  • If I did, I would have to handle myself 404 errors in my application (to show the `/404` page). IMO that's not a perfect solution (because I need to implement that at the PHP level, instead of Nginx), but I couldn't find any other so that's what I did. – Matthieu Napoli Sep 17 '14 at 11:46
  • Any web application that utilizes the front controller pattern must provide a 404 handler, because in order to make this pattern work, the web server must send all requests which don't match a static resource to the web application. – Michael Hampton Sep 17 '14 at 13:27
  • True but I was hoping for something like this: Nginx (not a static resource) => PHP app (not a route, return empty 404) => Nginx (404, intercept error) => redirect to `/404` => PHP app (generates the 404 page). – Matthieu Napoli Sep 18 '14 at 11:37
  • The PHP app should just send the 404 page the first time. – Michael Hampton Sep 18 '14 at 14:09
0

Make your script that generates the error page to return HTTP 200 (i.e. a proper page) and it should work right away.

nginx will retrieve the body of /404 and will update the response status to be 404.

P.S. as a bonus you may want to define an explicit location (e.g. location = /404 ) and turn fastcgi_cache on there so your PHP backend is not queried each time you need your error page displayed.

galaxy
  • 1,974
  • 1
  • 13
  • 15