Series - part 3 of 4

Ultimate Guide to Understanding HTTP Status Codes 500 – Internal Service Error


Before delving into a detailed technical discussion of cause behind 500 error code, it is important to understand what the error code 500 represents.

This post is part of the The Hypertext Transfer Protocol - HTTP series

In essence, a 500 error is delivered when, for some reason, the server could not process a client request due to a server error.

A 500 code can involve any of the following:

  • web-server configuration files
  • file-level permissions to scripts and/or logs
  • problem with the script interpreter
  • syntax error in a script
  • a logic error in a script
  • misconfiguration in a framework or Content Management System
  • client passing bad parameters in GET or POST request causing unforeseen errors in a script.

A 500 error represents the web-server being unable to fulfill a client request because an unknown error has occurred somewhere in the web stack. 

Google 500 Internal Server Error

Sometimes Google doesn’t even know what caused the error

The first thing to try is simply refreshing the web-page and rebooting the server.

If the server has just restarted, wait about 10 seconds then refresh the page. There is a possibility a web-page was requested before the web-server has completed into a running state.

Also, try other web-pages on the same site installation. This can quickly isolate a buggy script.


What Has Changed?

Since the last known-working-configuration, something has more than likely changed from when 500 Errors started appearing. Common scenarios are:

  • changes made to the HTTP server, PHP, or CMS configuration files
  • content management system updated
  • scripts re-written
  • new content added to a CMS
  • .htaccess files modified
  • server configuration modified
    • updated operating system
    • permissions changed
    • RDMS or Web-Server or PHP updated

If anything was recently modified look for ways to throw recent changes out of the equation.

Try using configuration files backed-up prior to edits. If no configuration files are backed up – backing up the current configuration files then running default configurations could help isolate the issue.

Check Your Server Logs

First backup the old logs.

  • stop server
  • backup logs
  • start server
  • tail logs while reproducing the 500 error
Using tail to view HTTP logs in real-time

with the -f switch tail will output lines to the terminal as they are logged

Troubleshooting a Buggy PHP Script

In this scenario a faulty PHP script is causing a 500 error: 

500 Error From Buggy PHP Script

First, let’s check our HTTP Logs. It’s always easiest to start with fresh logs:

mint / # mv /var/log/apache2/error.log /var/log/apache2/error001.bak
mint / # systemctl restart apache2
mint / # cat /var/log/apache2/error.log
[Fri Nov 24 11:16:45.689256 2017] [mpm_prefork:notice] [pid 6128] AH00163: Apache/2.4.18 (Ubuntu) configured -- resuming normal operations

Now that we have some fresh logs, let’s watch to see what happens as we call the page getting the 500 Error:

 mint / # tail -f /var/log/apache2/error.log
[Fri Nov 24 11:16:45.689256 2017] [mpm_prefork:notice] [pid 6128] AH00163: Apache/2.4.18 (Ubuntu) configured -- resuming normal operations
[Fri Nov 24 11:16:45.689373 2017] [core:notice] [pid 6128] AH00094: Command line: '/usr/sbin/apache2'
[Fri Nov 24 11:19:40.869980 2017] [:error] [pid 6131] [client 127.0.0.1:56694] PHP Parse error:  syntax error, unexpected 'echo' (T_ECHO) in /var/www/html/test.php on line 9

Let’s see what is happening on line 9 of our PHP script:

 mint ~ # cat -n /var/www/html/test.php
 1	<html>
 2	<head>
 3	<title>my php tester</title>
 4	</head>
 5	<body>
 6	<?php
 7	echo "PHP is good!";
 8	$php = "1"
 9	echo "PHP is great!";
10	?>
11	</body>
mint ~ # 

It looks as though someone forgot to terminate a line ending on line 8. Let’s fix it and see:

500 Fixed

Everything appears to be working fine now.

When troubleshooting 500 Status Codes as an Administrator, it is usually best to make configurations simple as possible to isolate any configuration issues. If possible take the following steps:

  • create a test directory with read, write, and execute permissions
  • make sure your test file has read, write and execute permissions
  • make a simple script in your preferred scripting language
  • see if the script works
mint ~ # mkdir /var/www/html/phptest
mint ~ # touch /var/www/html/phptest/php_test.php
mint ~ # chmod -R 777 /var/www/html/phptest/
mint ~ # ls -ld /var/www/html/phptest/
drwxrwxrwx 2 root www-data 4096 Nov 24 11:43 /var/www/html/phptest/
mint ~ # cat /var/www/html/phptest/php_test.php 
<html>
<head>
<title>PHP Testing</title>
</head>
<body>
<?php
phpinfo();
</body>
</html>
mint ~ # 

PHP Info Execution

Trouble Shooting Permissions

As a general rule of thumb, all folders and files in the web root should be read, write, execute for the root user. For the system account running the web-server files read execute. This translation is 755 in octal notation.

Linux file permissions are a little outside the scope of this article.

For more discussion on Linux, permissions follow the link below for a primer on file and folder permissions in Linux. Files and folder permissions for CentOS Linux

We can see the webroot and all files within have the proper permissions of 755

webroot permissions

If your webroot is large the following find options will list all files not read, execute: 

Finding Bad Permissions

using -type d instead of -type f, it is possible to list all directories not rw

Content Management System

To troubleshoot 500 errors in a CMS can be quite complex.

The first thing to try is making a second installation of your content management system in a default installation. Then test seeing if it still gets the 500 error. If the error still persists, it is a good bet the CMS is not the issue.

  • try removing all plugins
  • check recently configured files
  • try a default configuration file

Forums specific to your CMS always have knowledgeable users.

Check Script Interpreters

Make sure the script interpreter is the correct version for both script syntax and CMS: 

script interpreter

If edits have been made to scripting configuration file like php.ini – try backing up the current configuration and using the default configuration.

A default php.in for PHP 7 can be found in the official GIT Hub repository: Link to PHP 7.0 php.ini

Script timeouts are another cause of 500 errors. This can be caused be either logic errors (like an infinite loop) or script processing taking too long.

These settings can be adjusted in php.ini.

Prevention Is Key

The best way of preventing 500 errors is to keep separate development and production environments of your website.

Keeping a staging environment identical to production will give developers and designers the freedom of trying new a plugin, script fixes, CMS upgrades, and server configurations while greatly decreasing chances of a 500 Internal Server error on a production site.

All updates to scripting languages and servers should be first tested in a staging environment as well. This will prevent errors from being exposed on a live website.


501 – Not Implemented

501 Not Implemented is returned when a user-agent uses a request method is not supported by the web-server.

A lot of times web-servers will return 405 Method not allowed instead of 501 Not Implemented. The difference is “not implemented” should imply a request method is by the server but not allowed.

503 – Service Unavailable

Officially, as defined in RFC, 503 Service Unavailable is used when a production server is under maintenance. However, in today’s world with modern DevOps and distributed web services this is hardly the case.

More commonly today, 503 is used to keep content away from scraping bots with re-write rules.

RewriteEngine on
RewriteBase /
#for bots such as google
RewriteCond %{HTTP_USER_AGENT} ^.*(Googlebot|Googlebot|Mediapartners|Adsbot|Feedfetcher|bingbot)-?(Google|Image)? [NC]
RewriteCond %{ENV:REDIRECT_STATUS} !=503
RewriteRule !^/down/for/maintenance$ %{DOCUMENT_ROOT}down/for/maintenance [L,R=503]

Apache rewrite rule filtering spiders

504 – Gateway Timeout

A 504 Gateway Timeout is returned when communications between two servers, other than the client and host occur.

An example could be the web-server timing out before an expensive SELECT from a database is returned to a web application.

Troubleshooting a 504 Gateway Timeout involves first knowing what external server connection is the cause, then where the bottleneck resides.

Networking issues between two backend servers is a common issue with 504 Gateway Timeouts.

505 – HTTP Version Not Supported

505 HTTP Version Not Supported will result when a web-server does not support or is configured to refuse requests from unauthorized HTTP versions.

A 505 can be the result of either a user-agent using an outdated version of the HTTP protocol, the server using an outdated version of the protocol, or the web-server forcing user-agents to use a specific HTTP protocol version.

511 – Authorization Required

511 Auth Required was implemented to be used in conjunction with captive portals. 511 will be returned before connecting to a captive portal.