500 Internal Server Error: what it means and how to fix it
Kofi Agyem, Founder and CEO, CloudzyroPublished · 6 min read
On this page
A 500 Internal Server Error means the site's server hit a problem it can't handle. What causes it and how to fix it on nginx, Apache, Node and WordPress.
1. The short answer
A 500 Internal Server Error means the website's server ran into an unexpected problem and couldn't complete your request. It's the server's generic "something broke" code. The fault is on the site's side: usually a bug in the code, a bad configuration file, or a missing setting such as an environment variable or database password.
Codes in the 500s mean the server failed. A 500 comes from the app or server itself; a 502 or 504 comes from a proxy that couldn't get a good answer from the app behind it.
2. What you'll see
A plain "500 Internal Server Error" page, "HTTP ERROR 500" in Chrome when the server sends no page of its own, WordPress's "There has been a critical error on this website", or Next.js's "Application error: a server-side exception has occurred". Good apps hide the details from visitors and write them to a log.
3. Common causes
- An unhandled error in the code. A missing value, a typo, a function that throws, a failed API call nobody caught.
- A missing or wrong setting. An environment variable that isn't set, a wrong database password, an expired API key.
- The database is unreachable, or a query fails.
- A broken `.htaccess` file on Apache: a typo, or a module that isn't installed.
- PHP running out of memory (
Allowed memory size ... exhausted) or hitting its time limit. - A plugin or theme update that clashes with the PHP version or another plugin.
- Wrong file permissions on PHP files, on hosts that refuse to run scripts anyone can write to.
- A full disk, so the app can't write sessions, cache or logs.
4. How to fix a 500 as a visitor
- Refresh after a minute. Some 500s are brief.
- If you were submitting a form or paying, don't keep resubmitting. Check your email or account first so you don't pay twice.
- Try another page on the site. If only one page fails, tell the owner which.
- Check the site's status page or social accounts.
Clearing your cache rarely helps: the error happens on the server.
5. How to fix a 500 on your own site
Read the logs first. Everything else is guessing. Note the exact time, reproduce the error, and look at what was logged at that moment.
nginx with PHP-FPM. nginx's error.log often shows the PHP error passed back, as FastCGI sent in stderr: "PHP message: PHP Fatal error: ...". nginx rarely causes a 500 itself; one exception is a rewrite loop (rewrite or internal redirection cycle).
Apache and cPanel hosting. Check the error log for Invalid command (a .htaccess directive Apache doesn't recognize) or Request exceeded the limit of 10 internal redirects. Rename .htaccess to .htaccess.off; if the 500 goes away, the file is the problem. Check which PHP version the site uses, and look for an error_log file in the site's folder.
WordPress. Turn on logging in wp-config.php, reproduce the error, then read wp-content/debug.log. Rename the wp-content/plugins folder to rule out every plugin at once, then put them back one at a time.
// wp-config.php: log errors to a file, don't show them to visitors
define( 'WP_DEBUG', true );
define( 'WP_DEBUG_LOG', true );
define( 'WP_DEBUG_DISPLAY', false );Turn WP_DEBUG off again once you've found the cause.
Node and Express. Express's default error handler answers 500 for an error thrown in a route. Log the error with its stack, and catch errors in async code: an unhandled rejection can crash the whole process, which a proxy then reports as a 502.
// Express: log the real error, show visitors a plain message
app.use((err, req, res, next) => {
console.error(err);
res.status(500).send("Something went wrong on our side.");
});Next.js. The server logs print the full error; the page only shows a digest you can match against them. Check that every environment variable the server code needs is set where the app runs, not only in your local .env file.
Cloudflare. If the 500 page comes through Cloudflare, Cloudflare is passing on your server's 500, and the cause is still on your server. Cloudflare's own 52x codes mean something else: it couldn't reach your server properly.
6. On Cloudzyro
On Sites & Apps, a new version only goes live once it starts and its home page answers. If it crashes on start, for example because of a missing environment variable, the deploy fails with the reason, and the previous version keeps running. A 500 that appears after a version went live usually comes from a page or request that check didn't touch, so restore the previous version in one click while you fix it. Changes to environment variables apply on the next deploy. The failed deploy guide explains each reason a deploy stops.
On Web Hosting, sites run on cPanel. Choose each site's PHP version in cPanel's MultiPHP Manager, and fix .htaccess and permissions in File Manager.
7. A worked example
A shop owner updates a WordPress plugin, and every page shows "There has been a critical error on this website".
curl -I https://www.example.comreturnsHTTP/2 500.- She turns on
WP_DEBUG_LOG, reloads, and openswp-content/debug.log. - It shows
PHP Fatal error: Uncaught Error: Call to undefined functionin the plugin she just updated, which needs a newer PHP version. - She renames that plugin's folder and the site comes back. Then she moves the site to a newer PHP version and turns the plugin on again.
8. How to check the status code
# The status line and which server answered
curl -I https://www.example.com
# The body too, in case the app prints a hint
curl -i https://www.example.com/broken-pageIn a browser, open developer tools, choose the Network tab and reload. Click the failing request: the Status column shows 500, and the Response tab shows what the server sent.
9. Related errors
- [502 Bad Gateway](/guides/what-is-a-502-error): a proxy got a bad answer, or none, from the app.
- [503 Service Unavailable](/guides/503-service-unavailable): the service is overloaded or in maintenance.
- [504 Gateway Timeout](/guides/504-gateway-timeout): the app took too long to answer.
- [400 Bad Request](/guides/400-bad-request): the request itself was broken, not the server.
To hear about errors before your visitors tell you, set up uptime monitoring.