A blank page with three words: "500 Internal Server Error." No detail, no hint about what broke, and it can hit a WordPress site, a plain PHP script, a Laravel app, or a static HTML page sitting behind the wrong .htaccess rule. Unlike a 404, a 500 means the server tried to do something and choked partway through. Here's how to actually find out what, without guessing your way through random fixes.
Symptom: What a 500 Error Looks Like
It shows up a few different ways depending on the browser and server config:
- A bare "500 Internal Server Error" page with no styling, sometimes with "Apache" or "nginx" mentioned at the bottom
- A generic error from your CMS instead ("There has been a critical error on this website")
- The page loads for a few seconds, then times out with a 500 or 504
- Some pages work fine, others 500 — usually a sign it's script- or route-specific, not a global outage
Whatever the exact wording, the fix path is the same: find the real error first, then patch the actual cause.
Cause: Where 500 Errors Actually Come From
A 500 is a catch-all. The web server is saying "something on the backend failed" without saying what. In shared hosting and cPanel environments, it's almost always one of these:
| Cause | How it happens |
|---|---|
| Corrupted or misconfigured .htaccess | A bad rewrite rule, a directive your PHP handler doesn't support, or a stray character from a plugin/edit |
| Wrong file/folder permissions | Files not set to 644 or folders not set to 755 — often left behind by an FTP client or a bad ZIP extraction |
| PHP fatal error | A script calls a function that doesn't exist, hits a type error, or a required extension is missing |
| Exhausted resource limits | On CloudLinux-based shared hosting, hitting your account's entry process or CPU/memory limit (LVE) triggers a 500 instead of a slow load |
| mod_security rule block | A security rule flags something in a request (a query string, a POST body) as suspicious and kills it before it reaches your app |
| PHP version mismatch | Code written for PHP 7.x using syntax or functions removed in PHP 8.x, or vice versa |
| Database or cron timeout | A script waits on a slow query or external API call past the server's execution time limit |
Fix: Find the Real Cause First
1. Check the actual error log — don't guess
This is the step people skip, and it's the one that saves the most time. In cPanel, go to Metrics → Errors and look at the most recent entries for your domain. On a VPS, check:
tail -100 /var/log/apache2/error.log
# or, for Nginx
tail -100 /var/log/nginx/error.log
# for a specific PHP-FPM pool
tail -100 /var/log/php-fpm/www-error.log
You're looking for a line with a timestamp matching when the error happened. It'll usually name a file, a line number, and something specific — "Call to undefined function," "Permission denied," or a mod_security rule ID. That single line tells you which of the causes above you're actually dealing with, instead of trying all of them in sequence.
2. Rule out .htaccess by renaming it
Via File Manager or SSH, rename .htaccess in your site's root to .htaccess-broken, then reload the page. If the 500 disappears, the file itself is the problem:
- For WordPress, regenerate a clean one from Settings → Permalinks → Save Changes (this rewrites .htaccess with WordPress's default rules)
- For a custom app, restore from a backup or comment out rules one block at a time until you find the offending line
3. Fix permissions
Wrong permissions are a common, boring cause. From SSH, reset them safely from your site root:
find /home/username/public_html -type f -exec chmod 644 {} \;
find /home/username/public_html -type d -exec chmod 755 {} \;
Don't run this with 777 anywhere — that's a security hole, not a fix, and some hosts' security scanners will flag the account for it.
4. Check for a mod_security block
If the error log shows something like ModSecurity: Access denied with code 500, note the rule ID it mentions. Most hosting control panels let you view or request an exception for a specific rule ID on your domain rather than disabling mod_security entirely — ask your host's support team to whitelist that rule ID for your account if it's a false positive (common with page builders that submit large POST requests, like Elementor or WooCommerce checkout).
5. Check resource limits (CloudLinux/LVE)
In cPanel, scroll to Resource Usage on the dashboard. If "Entry Processes" or "CPU" shows consistently maxed out around the time of the error, your account hit its shared-hosting ceiling. A caching plugin, a lighter theme, or upgrading to a plan with higher limits (or a VPS) fixes this long-term; killing a runaway cron job or bot-triggered traffic spike fixes it short-term.
6. Match your PHP version to your code
In cPanel, go to MultiPHP Manager and check what version is assigned to the domain. If you recently got auto-upgraded to PHP 8.x and an old plugin or custom script wasn't written for it, that mismatch throws fatal errors. Either update the code or, as a short-term fix, select a compatible PHP version for that domain from the dropdown.
Prevention
- Keep a backup of a known-good
.htaccessbefore editing it by hand - Test plugin, theme, or code updates on a staging copy before pushing to production
- Watch your cPanel Resource Usage graph occasionally, not just when something breaks
- Set a PHP version explicitly per domain instead of leaving it on "inherit," so a server-wide upgrade doesn't surprise you
- Enable error logging (not display) in production so you have a paper trail when something does go wrong
Frequently Asked Questions
Is a 500 error always a hosting problem?
No. Most of the time it's caused by something in the site's own code, a plugin, or a misconfigured .htaccess — not the server itself. The error log will tell you which side it's on; if it points to a genuine server-level issue (disk full, service down), that's when it's time to open a ticket with your host.
Why does the error page not show any details?
Servers hide the specifics from visitors on purpose — showing raw PHP or database errors publicly can leak file paths or credentials. The real detail always lives in the server's error log, which only you (or your host) can see.
I renamed .htaccess and the 500 is gone, but now my site looks broken. What now?
That's expected — without .htaccess, URL rewriting (pretty permalinks, redirects) stops working, so pages that rely on it will 404 instead of loading. Restore a clean, regenerated .htaccess rather than leaving it renamed permanently.
Can a 500 error come and go on its own?
Yes, especially with resource-limit or mod_security causes. If it only happens under traffic spikes or on specific form submissions, that's a strong hint it's a limit or rule being triggered intermittently, not a permanently broken file.
How do I get to the error log without SSH access?
In cPanel, use Metrics → Errors — it shows the last several hundred lines of your domain's error log with no terminal needed. It's the fastest way to see what's actually failing.
