Common Causes
- Unhandled exception in your server-side code (PHP, Node.js, Python, etc.)
- Syntax error in a server-side file (e.g. broken .htaccess)
- Database connection failed — server can't connect to the database
- File permission error — server can't read/write a required file
- Out of memory — server ran out of RAM processing the request
- PHP fatal error — calling undefined function, requiring missing file
- Infinite loop or timeout in server-side code
How to Debug
500 errors are intentionally vague to users for security — the details are in the server logs:
# Apache error log (typical locations)
/var/log/apache2/error.log
/var/log/httpd/error_log
# Nginx
/var/log/nginx/error.log
# PHP (check php.ini for error_log location)
/var/log/php_errors.log
# Enable PHP errors temporarily (development only!)
ini_set('display_errors', 1);
ini_set('display_startup_errors', 1);
error_reporting(E_ALL);
⚠️ Never display errors in production. Error messages can expose file paths, database credentials, and code structure to attackers.
500 vs 502 vs 503
| Code | Meaning | Common Cause |
|---|---|---|
| 500 | Unhandled server error | Code bug, PHP fatal error |
| 502 | Bad Gateway — upstream server returned bad response | App server crashed, PHP-FPM down |
| 503 | Service unavailable | Overloaded server, maintenance |
| 504 | Gateway Timeout — upstream took too long | Slow database query, API timeout |
Prevention
- Always wrap database queries and external API calls in try/catch
- Validate configuration files before deploying (.htaccess, nginx.conf)
- Set up error monitoring (Sentry, Bugsnag) to catch unhandled exceptions
- Return structured error responses from APIs with helpful messages
- Use staging environments to test before deploying to production