Diagnosis guide
HTTP 500 Internal Server Error: What It Means and How to Find the Real Cause
A 500 Internal Server Error means your application crashed while handling the request — the server is running, but the code threw a fatal error it could not recover from. The generic 500 page is deliberately vague; the real message is written to your error log, not to the browser. The first thing to do is stop guessing and read the log: on most PHP stacks that is the web server or PHP-FPM error log, and on Node.js it is your process manager's output. The exact line that ends in "PHP Fatal error" or "UnhandledPromiseRejection" is the actual cause.
The symptom
Visitors see a bare "HTTP 500 Internal Server Error" or "The server encountered an internal error and was unable to complete your request" — sometimes a white screen with no text at all (the classic WordPress "white screen of death"). It can hit every page or just one URL, one form submission, or the admin area while the public site stays up. The status code returned is 500 (visible in the browser DevTools Network tab), which distinguishes a true application crash from a 502/503 (upstream or overload) or a 404 (missing route). Intermittent 500s that come and go usually point at resource limits or a flaky dependency rather than broken code.
What it usually means
A 500 almost always means the application code raised a fatal, uncaught error before it could send a normal response. The most common triggers are a PHP fatal error (a missing function, a class that no longer exists after an update, a syntax error in a recently edited file), an exhausted memory limit, a broken database connection, or a corrupt .htaccess directive. On frameworks like Laravel or a Node.js app it is typically an unhandled exception or a misconfigured environment variable. The key mental model from our hosting-support background: the server is fine, the application is what broke — so the fix lives in the app and its logs, not in restarting the machine.
What we check first
We go straight to the log, because it names the file and line. On Apache/PHP that is often /var/log/apache2/error.log or the site-specific log in the hosting panel; on nginx + PHP-FPM it is /var/log/nginx/error.log plus /var/log/php-fpm/www-error.log. We run tail -n 50 /var/log/nginx/error.log (or tail -f while reloading the page) and look for the line stamped "PHP Fatal error:" — for example "PHP Fatal error: Uncaught Error: Call to undefined function ... in /var/www/.../functions.php on line 42". For Laravel we open storage/logs/laravel.log; for Node.js we read pm2 logs or the container's docker logs. The second check is timing: what changed just before it started — a plugin update, a deploy, a PHP version bump, an expired credential? That single question resolves a large share of cases.
What you can safely check yourself
Open your browser's DevTools (F12) → Network tab, reload, and confirm the failing request really returns 500 and not 502/503 — this alone tells us whether to look at the app or the infrastructure. If you run WordPress, temporarily enable debug logging by setting define('WP_DEBUG', true); and define('WP_DEBUG_LOG', true); in wp-config.php, reload the page, then read wp-content/debug.log for the fatal line (turn it back off afterwards so errors are not shown publicly). Note exactly which URLs fail and which still work, and whether the problem started right after a specific update. If your host has a one-click "error log" viewer in cPanel or Plesk, copy the last few red lines — that is usually the answer.
What NOT to touch
Do not chmod 777 files or folders to "fix permissions" — it rarely helps and opens a real security hole; correct values are typically 644 for files and 755 for directories. Do not delete or blindly rewrite .htaccess, wp-config.php, or a framework .env file without a backup — a single stray character there causes an instant 500. Avoid mass-deleting plugins, clearing the database, or rolling the PHP version up or down while you are unsure of the cause; those change several variables at once and hide what actually failed. And never leave display_errors or WP_DEBUG on in production once you have the log line — it can leak file paths and credentials to visitors.
What a 30-minute diagnosis can determine
In a focused 30-minute session we can almost always find the exact failing file and line from the log and tell you the true root cause — a specific plugin conflict, a fatal after a PHP 8 upgrade, an exhausted memory_limit, or a dead database connection. We can confirm whether it is a code problem, a configuration problem (.htaccess, .env, credentials), or a resource limit, and give you a clear, scoped next step with an estimate. Often the fix itself is minutes away once the cause is named — reverting one file, bumping a limit, or disabling a single broken extension. You leave the session knowing what broke and what it will take to fully resolve it.
When it becomes a bigger job
It grows beyond a quick fix when the 500 is a symptom of something deeper: a botched or partial deployment, an incompatible major-version upgrade (PHP 7 to 8, a framework or WordPress core jump) that breaks many call sites, or code that was never compatible with the current environment. Database corruption, an out-of-memory server under real traffic, or a fatal that only appears intermittently under load also need proper investigation and testing rather than a one-line patch. In those cases the honest answer is a scoped remediation — reproduce, fix on a copy, verify, then deploy — instead of hot-patching production and hoping. We tell you upfront when a case is in that category so there are no surprises.
Quick checklist
- Confirm the failing request returns 500 (not 502/503/404) in DevTools → Network
- Read the server error log: tail -n 50 /var/log/nginx/error.log or your panel's log viewer
- Find the line starting "PHP Fatal error:" — it names the file and line number
- Ask what changed just before it started: update, deploy, PHP bump, expired credential
- For WordPress, enable WP_DEBUG_LOG and read wp-content/debug.log, then turn it off
- For Laravel check storage/logs/laravel.log; for Node.js read pm2/docker logs
- Note exactly which URLs fail versus which still work
- Back up .htaccess, wp-config.php or .env before changing anything
Frequently asked questions
What is the difference between a 500 and a 502 error?
A 500 means the application itself crashed while handling the request. A 502 (Bad Gateway) means the web server could not get a valid response from an upstream process — often PHP-FPM or a Node app that is down or timing out. Check the status code in DevTools to know which one you have.
How do I find the real cause of a 500 error?
Read the server error log, not the browser. Run tail -n 50 on your web server or PHP-FPM error log (or open the log viewer in cPanel/Plesk) and look for the "PHP Fatal error" line — it names the exact file and line that failed.
Why is my WordPress site showing a white screen instead of a 500?
It is the same crash; PHP display is off so you get a blank page. Set WP_DEBUG and WP_DEBUG_LOG to true in wp-config.php, reload, and read wp-content/debug.log for the fatal error, then switch debugging back off.
Can a plugin or a PHP update cause a 500 error?
Yes — very often. A plugin conflict, a bad update, or a PHP major-version upgrade (7 to 8) that leaves incompatible code is one of the most common causes. The log line will point to the specific file so you can identify the culprit.
Is a 500 error a problem with my hosting or my website?
Almost always the website (the application code or its configuration), not the server hardware. The server is running fine — it is your app that threw a fatal error. That is why the fix lives in the code, logs, and config rather than a server restart.
Will restarting my server fix a 500 error?
Usually not. Unless the crash was caused by a genuinely stuck process or exhausted memory, a restart changes nothing because the underlying code or config error is still there. Reading the log is faster and tells you what to actually fix.
If your site is down with a 500 and you would rather have someone read the log and name the cause than keep guessing, we can help. HelpApp Pro steps into your existing site or app remotely, finds the exact failing line, and tells you honestly whether it is a two-minute fix or a bigger job — billed in 30-minute increments, no subscription, with a reply within two business hours. See our Emergency website & app support page to get a diagnosis started.
Besoin d'une intervention ciblée ?
Décrivez le blocage — devis sans engagement, ou rappel sous 2 h ouvrées. Supplément urgence possible (+29.98€).