|
php.net | support | documentation | report a bug | advanced search | search howto | statistics | random bug | login |
[2010-02-03 04:23 UTC] phpbug at starurl dot com
Description: ------------ My host runs PHP v5.2.12 (confirmed via phpversion) on IIS6 (Windows Server, unknown version). When a PHP error occurs (parse error, runtime error, etc), a "200 OK" HTTP status is returned, instead of the correct "500 Internal Server Error". This is despite claims in the change history for v5.2.4 that this issue was fixed: "Changed error handler to send HTTP 500 instead of blank page on PHP errors. (Dmitry, Andrei Nigmatulin)". This doesn't appear to be the case on IIS6 (monitored remotely via HTTP Spy). Reproduce code: --------------- <? x = y; // cause parse error ?> Expected result: ---------------- Parse error mesage and "500 Internal Server Error" HTTP status code. Actual result: -------------- Parse error mesage and "200 OK" HTTP status code PatchesPull RequestsHistoryAllCommentsChangesGit/SVN commits
|
|||||||||||||||||||||||||||||||||||||
Copyright © 2001-2025 The PHP GroupAll rights reserved. |
Last updated: Tue Oct 28 16:00:01 2025 UTC |
Thank you for the swift response Jani. I can confirm that the 500 status code works for the following (runtime error): <? ini_set('display_errors', 0); $x = y(); ?> But fails for parse errors (because the "disply_errors" line doesn't get executed): <? ini_set('display_errors', 0); x = y; ?> Firstly, is this dependency really necessary? Just because we have 'display_errors' enabled doesn't mean we want fatal errors to go unlogged and unnoticed because a "200 OK" status is incorrectly returned. Secondly, the majority of PHP developers out there use shared hosting, on which 'display_errors' is normally true and is impossible to change globally - are we saying they're stuck with incorrect HTTP status codes when parse errors occur? The restriction that headers must not already have been sent is of course understandable as it is unavoidable. Not overriding an explicitly set HTTP status code also makes sense. But why not set the status code as "500 Internal Server Error" when any fatal parse/runtime error occurs, regardless of the value of 'display_errors'? This would be consistent with the HTTP spec, which recommends a 5XX response if an error occurs, and is followed by just about every other web server language out there (e.g., ASP, .NET). Many thanks, BJI am also having huge problems with this - haproxy health checks do not work reliably because of this bug. Please consider reopening it - it is not bogus. PHP doesn't return HTTP error code, even if display_errors is set to 0. One example: <? ini_set('display_errors',0); this_function_does_not_exist(); echo "ok"; ?> This returns an empty page with status code 200: ----- HTTP/1.1 200 OK Date Fri, 12 Mar 2010 07:27:15 GMT Server Apache/2.2.9 (Debian) PHP/5.2.6-1+lenny6 with Suhosin-Patch X-Powered-By PHP/5.2.6-1+lenny6 Vary Accept-Encoding Content-Encoding gzip Content-Length 20 Keep-Alive timeout=15, max=100 Connection Keep-Alive Content-Type text/html ----- Content-Length is 20, probably because of gzip? There are no spaces around PHP block in source code. I have checked phpinfo() and display_errors is set to Off, so there is no error there. Also, I have tried setting it in php.ini - no change. Another problem: parse errors are also not handled correctly (even if display_errors is set to 0 in php.ini). See previous poster's example. Thanks!A workaround for those interested is the following: register_shutdown_function(function() { $error = error_get_last(); if ($error['type'] == E_ERROR) { header('HTTP/1.1 500 Internal Server Error'); } }); Be nice to see this fixed without this workaround though.You can't completely fix this by the way http works. <?php echo 'x'; ob_flush(); // http status code and headers are now sent to client eval('x=y'); // error detected here no matter which technology stack, after you've sent everything is 200 OK you can't signal the client something went wrong. You shouldn't monitor your service through status codes only because of this edge case. Monitor your logs.i've done this to solve the problem: register_shutdown_function( "fatal_handler" ); function fatal_handler() { http_response_code (500); }Just so you know, I had this same issue and I had to change my "error_reporting" value to the resolved integer value ("E_ALL & ~E_NOTICE & ~E_STRICT & ~E_DEPRECATED" -> 30711) [Based on this: https://www.php.net/manual/en/errorfunc.constants.php] since I'm trying to use an environment variable within the configuration file and it doesn't seem to resolve the constants properly.in php 8.2 it returns a 200 response code even if using header and http_response_code <?php register_shutdown_function('shutdown_handler'); echo "Hello"; while(true) $data .= str_repeat('#', PHP_INT_MAX); function shutdown_handler() { header($_SERVER['SERVER_PROTOCOL'].' 500 Internal Server Error', true, 500); http_response_code(500); print_r(error_get_last()); }