Fix '500 Internal Server Error' in 5 Steps
That generic 500 error on your IIS or Apache server? Usually a bad config, permissions, or a coding crash. Here's how to nail it fast.
First: Check the Browser's Clue (30 Seconds)
Before you touch anything, look at the full error message. Most 500 errors hide a detail in the browser or server response. On IIS, you'll sometimes see 500.0, 500.13, or 500.19 — each points to a different root cause. On Apache, the error might say Premature end of script headers or Permission denied.
Open your browser's developer tools (F12), go to the Network tab, reload the page, and click the 500 entry. Check the Response tab for extra text. If you see something like Maximum execution time of 30 seconds exceeded, you're done in the next step. If not, move on.
Second: Tweak the Easy Stuff (5 Minutes)
Check File + Folder Permissions
The culprit here is almost always the web server user (IUSR on IIS, www-data on Apache) missing read or execute rights. For IIS:
icacls C:\inetpub\wwwroot\your-site /grant IUSR:(RX)For Apache:
chown -R www-data:www-data /var/www/your-site
chmod -R 755 /var/www/your-siteDon't bother with 777 — that's lazy and a security hole. Stick with 755 for directories, 644 for files.
Bump PHP Memory or Execution Time
If you're on PHP and the error appears on large uploads or complex pages, memory or time limits are the issue. Edit php.ini:
memory_limit = 256M
max_execution_time = 120Restart the web server after. If you're on shared hosting, add this to .htaccess:
php_value memory_limit 256M
php_value max_execution_time 120Reset Web.Config or .htaccess
Sometimes a botched config change kills the app. Rename your web.config (IIS) or .htaccess (Apache) to web.config.bak and reload the page. If the error disappears, you know that file is the root cause. Recreate it from a clean backup or known working version.
Third: Dig Into Server Logs (15+ Minutes)
If the simple fixes didn't work, the answer lives in the logs. Here's exactly where to look:
- IIS:
C:\inetpub\logs\LogFiles\W3SVC[your-site-ID]for HTTP logs. Also check Event Viewer -> Windows Logs -> Application for ASP.NET crash details. - Apache: Usually
/var/log/apache2/error.logor/var/log/httpd/error_log. Tail it live withtail -f /var/log/apache2/error.logwhile reproducing the error. - PHP: Look in
/var/log/php_errors.logor wherever yourerror_logdirective points.
Read the last 50 lines. You'll likely see one of these patterns:
PHP Fatal error: Uncaught Error: Call to undefined function— a coding bug. Roll back recent changes.Permission denied: /var/www/your-site/wp-content— I see this constantly with WordPress. Fix perms.[core:error] [pid 12345] (13)Permission denied: file permissions deny server access— same deal.FastCGI process exited unexpectedly— often a PHP crash. Bump memory limit or update PHP version.
Fix .NET Application Pools (IIS Only)
If you're running an ASP.NET app and get a 500.0, the application pool is likely running as a user that can't read the app's folder. Open IIS Manager, go to Application Pools, select your app pool, click Advanced Settings, and set Process Model > Identity to ApplicationPoolIdentity (recommended) or a specific service account. Then recycle the pool.
Check for .htaccess Loop (Apache)
I've seen RewriteRule directives that cause an infinite loop, which eventually throws a 500. Disable all rewrite rules temporarily by commenting them out in .htaccess. If the site loads, add rules back one by one until you find the bad one.
When Nothing Works: Blow Away and Rebuild
If you've checked permissions, logs, and configs, and still get a 500, sometimes the fastest fix is to restore from a clean backup or re-deploy the app from source control. I've spent two hours chasing a 500 only to find a corrupted DLL. Restoring took five minutes. Know when to cut your losses.
Pro tip: Set up a staging environment that mirrors production. Reproduce the 500 there before touching the live server. Saves your ass more times than I can count.
Was this solution helpful?