Home Server Nginx Solution to: How do I prevent WordPress 3.7.1 from returning a 500...

Get social!

Note: This is a solution in that it fixes the problem, but not really a full answer. Feel free to comment to fill in the missing pieces. Also note that in the end I created a plugin to solve this issue. The source is at the end of the post.

When trying to install a new WordPress instance on Ubuntu Server + Nginx, I would continually receive a 500 server error when trying to run the installer. The Nginx logs showed nothing of value — not even the 500 error! What? The error should be reported in the logs, right?

Solution

Turns out that WordPress’s function, wp_die() generates the 500 error through PHP. That’s why I didn’t see anything in the log. Digging through the code, I found that in this case the wp_die() function outputs additional html, which which looks like this (but prettier):

There doesn’t seem to be a wp-config.php file. I need this before we can get started.

Need more help? We got it.

You can create a wp-config.php file through a web interface, but this doesn’t work for all server setups. The safest way is to manually create the file.

Create a Configuration File

« Back

That’s what I expect to see. However, for some reason — and this constitutes the incomplete answer part — the Nginx server ignores the output and sends the regular 500 error page instead. Perhaps this is because I have custom error pages set in Nginx, I don’t know. At any rate, the issue as related to WordPress is that wp_die() in wp-load.php sends a 500 error by default. The original problem code is in wp-load.php (WP version 3.7.1):

Line 61 above is the culprit. We can change the server response code to something more palatable to Nginx by passing the wp_die() function a WP_Error object instead of a simple string:

The 'response' => '406' tells wp_die() to send a 406 server error response instead of a 500 error. I’m not sure if the 406 code (Not Acceptable) is the most appropriate code to use here, but it seems to work OK.

Caveats

  • One problem is solved, but if WordPress uses wp_die() with a plain text string anywhere else, the same problem will recur. I’m tempted to modify the wp_die() function to return a 406 server error by default, but that could cause other, unforeseen problems, so for now we’ll let things be.
  • I despise changing the WP source code! I really should look into the root cause of the problem, which I suspect is my custom error pages. The first WP update will undo everything I’ve created.

Update

Since I started to encounter the same problem on other pages with WordPress, I modified the wp_die() function to output a 406 error by default. The actual function to modify  is _default_wp_die_handler() in wp-includes/functions.php.

Update

Because this problem was recurring throughout WordPress, I created a plugin to return a 406 result by default in all cases. This has the added benefit of not mucking with the WordPress code directly, but it’s still a monkey-patch and can break if the default function ever changes in WordPress. Here’s the plugin source (Overly complex. Sorry.):

Leave a Reply

Bad Behavior has blocked 48 access attempts in the last 7 days.