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?
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.phpfile. I need this before we can get started.
Need more help? We got it.
You can create a
wp-config.phpfile 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
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-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:
'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.
- 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.
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.
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.):