This document demonstrates debugging a web server returning HTTP 500 errors by investigating logs, configuration files, process information, and file permissions. Focus is on systematic investigation and root cause identification.
This document walks through debugging a web server returning HTTP 500 errors, demonstrating systematic investigation of logs, configuration files, running processes, and file permissions to identify and resolve the root cause.
When a web server returns an HTTP 500 Internal Server Error, the root cause typically lies on the server side. This requires systematic investigation of logs, configurations, running processes, and system resources to identify the issue.
The first step is to confirm the error by accessing the failing webpage. An HTTP 500 response indicates a server-side crash or misconfiguration, but provides no details about the underlying cause.
On Linux systems, logs are located in /var/log. Use date and time information to narrow the search:
1# Check current date
2date
3
4# Navigate to log directory
5cd /var/log
6
7# List files sorted by modification time (most recent first)
8ls -lt | head -n 10
9
10# Check recent entries in syslog
11tail /var/log/syslog
If no relevant errors appear in system logs, the issue may be application-specific.
When the web server software is unknown, identify which process is listening on port 80:
1# Find process listening on port 80
2sudo netstat -nlp | grep :80
| Flag | Purpose |
|---|---|
-n | Print numerical addresses instead of resolving hostnames |
-l | Show only listening sockets |
-p | Display process ID and name for each socket |
Example output reveals nginx is listening on port 80.
Configuration files on Linux are typically stored in /etc. For nginx:
1# Navigate to nginx configuration
2cd /etc/nginx
3
4# Check site-specific configurations
5ls /etc/nginx/sites-enabled/
Example nginx site configuration:
1uwsgi_pass 127.0.0.1:3031;
This indicates nginx is proxying requests to uWSGI (a common solution for connecting web servers to dynamic page generators).
1# Navigate to uWSGI configuration
2cd /etc/uwsgi/apps-enabled
3
4# Review site configuration
5vi site.example.com.ini
Key configuration details:
| Parameter | Value | Purpose |
|---|---|---|
chdir | /srv/site.example.com | Application directory |
uid/gid | www-data | User and group for running the app |
wsgi-file | prod.py | Python script to execute |
logto | /var/log/site.log | Application log file |
1# Check log file
2ls -lh /var/log/site.log
If the log file is empty or missing, enable debug mode in the application.
Review the Python application:
1# Open application file
2sudo vi /srv/site.example.com/prod.py
Uncomment debug line:
1# Before:
2# bottle.debug(True)
3
4# After:
5bottle.debug(True)
1# Reload uWSGI to apply changes
2sudo service uwsgi reload
After enabling debug mode, reload the webpage. The error traceback reveals:
1PermissionError: [Errno 13] Permission denied: '/var/log/site.log'
1# Check log files
2ls -l /var/log/site*
Example output:
| File | Owner | Group | Permissions |
|---|---|---|---|
site.log | root | root | -rw-r--r-- |
site.log.1 | www-data | www-data | -rw-r--r-- |
The application runs as www-data but site.log is owned by root, preventing write access.
1# Change owner to match application user
2sudo chown www-data:www-data /var/log/site.log
Reload the webpage to confirm it now works correctly. The log file will populate with entries as requests are processed.
The immediate issue is resolved, but the root cause (why the file ownership was incorrect) requires further investigation:
/etc/logrotate.d/)| Step | Action |
|---|---|
| 1. Reproduce | Confirm the error occurs |
| 2. Check logs | Review system and application logs |
| 3. Identify process | Use netstat to find listening services |
| 4. Review config | Examine web server and application configuration |
| 5. Enable debug | Activate verbose logging or debug mode |
| 6. Analyze errors | Read tracebacks and error messages |
| 7. Apply fix | Address the identified root cause |
| 8. Verify | Confirm the issue is resolved |
| 9. Remediate | Prevent recurrence through configuration or monitoring |
An internal server error is a Hypertext Transfer Protocol (HTTP) response, communicating to the user that an error occurred before completing a specific request. In short, the server tried to do something, but it failed. The most common internal server error is an HTTP 500 error, but other common error codes include 200, 301, 302, 304, 403, 404, and 503. Here is an example of what an internal server error might look like in a browser:
A Google website that displays a 500 error message informing the user that something is wrong with the server.
Internal server errors can occur for different reasons, including various glitches in the website’s programming. Typically, this type of error occurs when there are bugs in the code. They can also occur if a database becomes unavailable, the server runs out of memory, or the application encounters a permission error. The downside to internal server errors is that they do not provide you with information on what exactly is wrong. As a developer, the error code only provides the general type of error occurring. Run different tests or set various parameters to try to reproduce the error. If you can reproduce the error, that will help you identify the issue and correct it.
An internal server error is displayed when a web server cannot fulfill or complete a request. An internal server error informs you that an error exists but does not tell you exactly what the error is or where it is located. Troubleshoot by running tests to determine what and where the bugs are in your code and correct them to eliminate internal server errors.
Systematic investigation of web server errors involves checking logs, identifying running processes, reviewing configurations, enabling debug output, and analyzing permissions or resource constraints. Each step narrows the scope until the root cause is identified and resolved.