PHP fatal errors come back as status code 200 to the HTTP client. How can I make it return a status code 500 (Internal server error)?
-
the fact php return an error that is not related to the HTML header you get in the browser. If you run that script from the command line you wont get any 200 error code – Gabriel Sosa Oct 12 '09 at 18:27
-
See http://stackoverflow.com/questions/2331582/catch-php-fatal-error for a solution. – cweiske Apr 14 '11 at 11:43
-
I need the exact opposite. I have set up a shutdown function that with `auto_prepend_file` catches all fatal errors. However, I also want to have `status code 200` sent when that function is invoked. But I keep getting `status code 500`. – Majid Fouladpour Jun 30 '15 at 14:08
10 Answers
header("HTTP/1.1 500 Internal Server Error");

- 219,335
- 46
- 382
- 435
-
@DrewSears I don't think you "have" to; you could just use the `Status` header field just like in CGI. But it must be said that for PHP programmers unfamiliar with CGI, the "HTTP/1.1" syntax is easier to read, because, well, it mimics an HTTP response. – C. K. Young Jun 15 '12 at 06:02
-
7Since PHP >= 5.4 there is the `http_response_code([int $responseCode])` function. – Lars Nyström Jul 28 '16 at 09:40
This is exactly the problem I had yesterday and I found solution as follows:
1) first of all, you need to catch PHP fatal errors, which is error type E_ERROR. when this error occurs, script will be stored the error and terminate execution. you can get the stored error by calling function error_get_last().
2) before script terminated, a callback function register_shutdown_function() will always be called. so you need to register a error handler by this function to do what you want, in this case, return header 500 and a customized internal error page (optional).
function my_error_handler()
{
$last_error = error_get_last();
if ($last_error && $last_error['type']==E_ERROR)
{
header("HTTP/1.1 500 Internal Server Error");
echo '...';//html for 500 page
}
}
register_shutdown_function('my_error_handler');
Note: if you want to catch custom error type, which start with E_USER*, you can use function set_error_handler() to register error handler and trigger error by function trigger_error, however, this error handler can not handle E_ERROR error type. see explanation on php.net about error handler

- 13,431
- 9
- 55
- 73

- 2,573
- 4
- 23
- 46
-
6Be sure to also use `ini_set("display_errors", "off");` in a production environment, otherwise the fatal error messages will be sent back to the client. – alexw Mar 06 '15 at 01:55
-
1I suggest checking for E_PARSE as well - that's also catchable in this way, provided the shutdown function is set before the file with the parse error in it is included. – Brilliand Oct 27 '15 at 17:18
Standard PHP configuration does return 500 when error occurs! Just make sure that your display_errors = off. You can simulate it with:
ini_set('display_errors', 0);
noFunction();
On production display_errors directive is off by default.

- 7,595
- 3
- 37
- 31
-
This should be higher up. This is actually the correct way of setting up the server to return 500 on fatal errors. If you need to see the error messages, you should be using the error log. – Dan H Jul 31 '18 at 10:19
-
Isn't this true only **if** php has **not** already output something (aka headers already sent)? Aside: it looks like php 8.1+ will accept all scalar types for the 2nd arg to ini_set(). – DWB Jan 15 '23 at 03:46
Since PHP >= 5.4
http_response_code(500);
echo json_encode( [ 'success' => false , 'message' => 'Crazy thing just happened!' ]);
exit();
Please set the httpCode before echo
.

- 5,769
- 1
- 46
- 43
I have used "set_exception_handler" to handle uncaught exceptions.
function handleException($ex) {
error_log("Uncaught exception class=" . get_class($ex) . " message=" . $ex->getMessage() . " line=" . $ex->getLine());
ob_end_clean(); # try to purge content sent so far
header('HTTP/1.1 500 Internal Server Error');
echo 'Internal error';
}
set_exception_handler('handleException');

- 71
- 1
- 2
-
You can do this if you want to handle fatal errors: http://stackoverflow.com/questions/277224/how-do-i-catch-a-php-fatal-error – John Hunt Mar 22 '13 at 14:38
-
2Use both set_error_handler and set_exception_handler. The first one is for old style fatal errors, the second one is for object-oriented exceptions. – Ron Inbar May 12 '14 at 14:10
It is not possible to handle PHP E_ERROR in any way according to the PHP documentation: http://www.php.net/manual/en/function.set-error-handler.php
Nor is is possible to handle "E_PARSE, E_CORE_ERROR, E_CORE_WARNING, E_COMPILE_ERROR, E_COMPILE_WARNING, and most of E_STRICT" according to that link.
You CAN provide a handler for the other error, warning, and notices including E_USER_ERROR, but that's really not as useful as it sounds since this error only gets thrown intentionally by the programmer with trigger_error().
And of course you can catch any Exception (even the ones thrown by the native PHP functions).
I agree that this is a problem. Servers should NOT return 200 OK when application code crashes and burns.

- 4,661
- 1
- 19
- 16
-
replying to super old answer here... but as of php 5.2... you can use `error_get_last()` inside the shutdown function.. if the last error was fatal.. tada – Brad Kent Mar 16 '18 at 14:40
Never forget to set header("HTTP/1.1 200 OK", true, 200);
as the last line of any execution path:
//first things first:
header("HTTP/1.1 500 Internal Server Error", true, 500);
//Application code, includes, requires, etc. [...]
//somewhere something happens
//die();
throw new Exception("Uncaught exception!");
//last things last, only reached if code execution was not stopped by uncaught exception or some fatal error
header("HTTP/1.1 200 OK", true, 200);
In PHP 5.4
you can replace the header
function above with the much better http_response_code(200)
or http_response_code(500)
.

- 5,891
- 6
- 37
- 69
-
2That doesn't work if any output is generated between the first and last `header()` call, because then the header will have already been sent. Working pages may be delivered with status 500. This approach is way too risky. – Peter Feb 07 '14 at 13:10
-
Use output buffering and output after the header. Which is obvious. If output buffering fails in any way, thats not a working page, its a buggy page. – oxygen Feb 07 '14 at 15:08
The hard thing when dealing with fatal errors (compile errors, for example a missing semicolon) is that the script won't be executed, so it won't help to set the status code in that script. However, when you include or require a script, the calling script will be executed, regardless of errors in the included script. With this, I come to this solution:
rock-solid-script.php:
// minimize changes to this script to keep it rock-solid
http_response_code(500); // PHP >= 5.4
require_once("script-i-want-to-guard-for-errors.php");
script-i-want-to-guard-for-errors.php:
// do all the processsing
// don't produce any output
// you might want to use output buffering
http_response_code(200); // PHP >= 5.4
// here you can produce the output
Direct your call to the rock-solid-script.php and you're ready to go.
I would have liked it better to set the default status code to 500 in .htaccess. That seems more elegant to me but I can't find a way to pull it off. I tried the RewriteRule R-flag, but this prevents execution of php altogether, so that's no use.

- 134
- 1
- 3
You can use php error handling

- 29,617
- 32
- 119
- 165
-
10Good answer consists more than just linking to other pages. You could for example refer that page shortly. What happens when destination site is down or they move that content? Also, w3schools are not-so-good source. – Olli Apr 08 '12 at 17:15
You would have to catch the thrown error using try/catch and then use that catch block to send a header() with the 500 error.
try {
...badcode...
throw new Exception('error');
} catch (Exception $e) {
header("Status: 500 Server Error");
var_dump($e->getMessage());
}
If the fatal exception is not surrounded by try {} catch blocks then you must register a global handler and use register_shutdown_function()
to check for an error at script end.

- 55,620
- 80
- 262
- 364
-
7That will catch exceptions, but it won't catch PHP Fatal errors, which are handled outside the scope of exceptions. – Alana Storm Oct 12 '09 at 17:33
-
3Fatal/syntax errors can't be captured as far as i know, neither by errorhandling nor by exceptionhandling – ChrisR Oct 12 '09 at 19:13
-
@ChrisRamakers: I've read something about using output handlers to catch PHP fatal errors. – Alix Axel Jan 24 '10 at 02:49
-
depends, syntax errors are triggered at compile time thus the logic that handles output or exception handling simple never occurs because the page is simply not executed because i could not be compiled. But again, i'm not an absolute expert so i might not be aware of the output handlers you are talking about – ChrisR Jan 26 '10 at 21:24
-
Actually, you use `register_shutdown_function()` to catch E_FATAL errors. – Xeoncross Aug 18 '10 at 02:08