php.net |  support |  documentation |  report a bug |  advanced search |  search howto |  statistics |  random bug |  login
Bug #50921 '200 OK' HTTP status despite PHP error
Submitted: 2010-02-03 04:23 UTC Modified: 2014-07-09 23:00 UTC
Votes:6
Avg. Score:4.5 ± 0.8
Reproduced:4 of 4 (100.0%)
Same Version:0 (0.0%)
Same OS:0 (0.0%)
From: phpbug at starurl dot com Assigned:
Status: Re-Opened Package: HTTP related
PHP Version: 5.2.12 OS: *
Private report: No CVE-ID:
Have you experienced this issue?
Rate the importance of this bug to you:

 [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

Patches

Add a Patch

Pull Requests

Add a Pull Request

History

AllCommentsChangesGit/SVN commitsRelated reports
 [2010-02-03 10:06 UTC] jani@php.net
It does happen. It requires that:

1) display_errors = off
2) No headers have been sent yet by the time the error happens
3) Status is 200 at that time.

 [2010-02-03 18:01 UTC] phpbug at starurl dot com
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,  BJ
 [2010-02-03 19:03 UTC] derick@php.net
The reason why display errors needs to be turned of, is because displayed errors generate output, and output causes the headers to be send out. I'm afraid we can't do much about this.
 [2010-03-12 08:37 UTC] anzenews at volja dot net
I 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!
 [2010-03-12 16:04 UTC] pajoye@php.net
-Operating System: Windows IIS6 +Operating System: *
 [2010-08-12 15:35 UTC] tyra3l at gmail dot com
I can reproduce the problem.
I found out, that if I enable xdebug, then I get header 200, if I disable it, then 
it's 500.
Will report it to Derick.

Tyrael
 [2010-08-12 15:40 UTC] tyra3l at gmail dot com
It's seems that this is a known bug in the xdebug, see:
http://bugs.xdebug.org/view.php?id=587

but couldn't fix it without making some changes in php itself:

"Before I can address this, there need to be some changes in PHP itself. It 
doesn't expose some required information to extensions yet that I will need."

I hope this get fixed soon.

Tyrael
 [2010-11-19 11:48 UTC] dean at deansas dot org
> The reason why display errors needs to be turned of, is because
> displayed errors generate output, and output causes the headers 
> to be send out. I'm afraid we can't do much about this.

Can't PHPs error handling first set a 500 header and then output
error messages as appropriate? 

It doesn't seem to me like this is something that can never ever be fixed
 [2013-04-13 19:01 UTC] matteosistisette at gmail dot com
The status is wrong. And oh my god, since 2010!!

This IS a bug.

Display_errors off means don't DISPLAY errors, it shouldn't have any effect on 
the response code.

Default response for fatal errors should be 500 whether or not display_errors is 
turned on.
 [2013-05-28 21:42 UTC] kwintersnc at gmail dot com
According to http://bugs.xdebug.org/view.php?id=587 this is fixed in PHP 5.4, so 
"Not a bug" isn't correct.
 [2014-04-28 14:40 UTC] ruben at rubensayshi dot com
still having this issue with "PHP Version: 5.4.27-1+deb.sury.org~precise+1" with xdebug turned on or off, doesn't seem to make a difference ...

display_errors off does, as already stated by others.
 [2014-06-02 15:21 UTC] brenjt at gmail dot com
I can also confirm the issue still exists: PHP Version 5.4.16
 [2014-06-24 22:01 UTC] derek at derekperkins dot com
This is an error for us as well, running on 5.4.28 on Google App Engine, with and without XDebug. This definitely needs to be fixed.
 [2014-06-25 08:10 UTC] tyrael@php.net
the xdebug issue was a separate problem, and is indeed fixed.
what is still not "fixed" is that if you enable display_errors, then the error message itself will trigger sending out the response which sets the http 200 implicitly.
if we go ahead and change this, we should make sure to only add the http 500 when the script execution is actually terminated by the error(for example E_RECOVERABLE_ERROR will or won't stop the execution based on the return value of the user defined error handler) as we don't wanna start sending http 500 responses for every notice and stuff.
 [2014-06-25 08:57 UTC] tyrael@php.net
oh, it seems we are explicitly checking for display_errors when setting the 500 response code:
http://lxr.php.net/xref/PHP_5_4/main/main.c#1154
I will ask the others on the internals list for the reason for this.
 [2014-07-08 17:19 UTC] jonathan at spoonity dot com
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.
 [2014-07-08 19:28 UTC] tyrael@php.net
-Status: Not a bug +Status: Re-Opened
 [2014-07-08 19:28 UTC] tyrael@php.net
here is the thread I've started about this behavior:
http://www.serverphorums.com/read.php?7,965893
it turned out that we added the explicit display_errors check for not setting the http 500 response code because Internet Explore will show a custom error page for non-2xx responses if the length of the response body is less than an arbitrary threshold, hence it won't show the error message if we set the http 500.
I don't think that this change was a good idea back then, but it is possible that changing it now would cause more harm than good.
I will keep this ticket open until we either reach a consensus that this should be fixed in a future release, or should be kept as-is and the documentation is updated to reflect current behavior.
 [2014-07-08 20:38 UTC] jonathan at spoonity dot com
Ah yes, I remember that. The IE limit a minimum of 512 byte of data to show  the outputted data. Perhaps there could be an ini setting to choose if the status code will be 200 or 500, with the default being the current behaviour?
 [2015-05-25 17:33 UTC] josh dot ribakoff at gmail dot com
+1

This is a BUG in my books. Until it is fixed, I can't simply tail an error log. Instead I'd have to go manually exercise every feature & invoke every code path in my app & painstakingly analyze the network responses of all my ajax calls to detect any possible errors. Horrible.
 
PHP Copyright © 2001-2015 The PHP Group
All rights reserved.
Last updated: Tue May 26 09:02:17 2015 UTC