500 Internal Server Error: What It Means & How to Fix It

By 

Updated on

14 min read

500 Internal Server Error

The 500 Internal Server Error is an HTTP status code that indicates the web server encountered an unexpected condition and could not complete the request. It is a generic server-side error: the server knows something went wrong but cannot be more specific about the cause.

This guide explains what causes a 500 error, how to diagnose it using server logs, and the most common fixes for web servers like Apache and Nginx.

Quick Reference

CauseFix
File/directory permission issuefind /var/www/html -type d -exec chmod 755 {} +, find /var/www/html -type f -exec chmod 644 {} +, then chown -R www-data:www-data /var/www/html
.htaccess syntax errorCheck syntax or temporarily rename the file
PHP errorCheck the active PHP error log and the web server error log
Exhausted memory or diskCheck with free -h and df -h
Database connection failureVerify credentials and service status with systemctl status mysql
Broken plugin or theme (CMS)Disable recently updated plugins via CLI or file manager
PHP-FPM application error (Nginx)Check both logs; the PHP-FPM log usually has the application error: sudo tail -50 /var/log/php8.3-fpm.log
Nginx rewrite loop or bad configRun nginx -t, then grep the error log for redirection cycle
SELinux denial (Fedora, RHEL)sudo restorecon -Rv /var/www/html

What Is an HTTP 500 Error

When you open a web page, your browser sends a request to the server hosting the site. The server processes the request and returns an HTTP response code along with the requested content. Response codes in the 200 range indicate success, while codes in the 500 range indicate a server error.

The 500 status code is the most general server error. The server returns it when no more specific error code (such as 502, 503, or 504) applies.

Error 500

What Visitors Can Do

If you encounter a 500 error while browsing a website, the problem is on the server side, not with your browser or internet connection. You can try the following:

  • Reload the page: The error may be temporary. Wait a few seconds and refresh.
  • Clear your browser cache: If the error page is cached, your browser may keep showing it. Clear the cache and try again.
  • Try a different browser or device: This helps rule out browser-specific caching issues.
  • Come back later: The server administrator may already be working on a fix.
  • Contact the website owner: If the error persists, let them know so they can investigate.

Common Causes and Fixes

If you are the server administrator, the following are the most common causes of a 500 Internal Server Error and how to fix them.

File Permission Issues

The web server process needs read access to your site files and execute access to directories. Incorrect file permissions are one of the most frequent causes of 500 errors.

To fix permissions for a typical web root:

Terminal
sudo find /var/www/html -type d -exec chmod 755 {} +
sudo find /var/www/html -type f -exec chmod 644 {} +
sudo chown -R www-data:www-data /var/www/html

Replace www-data with the user your web server runs as (e.g., nginx or apache).

.htaccess Syntax Errors

If you use Apache, an invalid directive or syntax error in the .htaccess file causes a 500 error. Common mistakes include typos, referencing modules that are not loaded, and incorrect rewrite rules.

To test, temporarily rename the file:

Terminal
sudo mv /var/www/html/.htaccess /var/www/html/.htaccess.bak
Warning
Renaming .htaccess disables every rule it contains, including redirects, access restrictions, and HTTPS enforcement, for as long as the file is renamed. Do this only long enough to confirm the cause, then restore the file.

If the site loads after renaming, the problem is in the .htaccess file. Review it line by line or check the Apache error log for the specific directive that failed.

PHP Errors

A fatal PHP error (such as a syntax error, missing extension, or exceeded memory limit) causes the server to return a 500 error instead of rendering the page.

Check the PHP error log or the web server error log:

Terminal
sudo tail -50 /var/log/apache2/error.log

For Nginx with PHP-FPM:

Terminal
sudo tail -50 /var/log/nginx/error.log

If the error is a memory limit issue, increase the memory_limit value in the active php.ini file for your PHP runtime. PHP CLI and PHP-FPM can load different configuration files, so do not use php --ini to locate the file used by web requests. On Ubuntu and Debian, the FPM file is normally under /etc/php/<version>/fpm/php.ini. Fedora and RHEL normally use /etc/php.ini.

Edit the appropriate PHP-FPM configuration file:

Terminal
sudo nano /path/to/php.ini

Find the memory_limit line and increase it:

ini
memory_limit = 256M

Restart the PHP service after making changes.

Nginx and PHP-FPM Failures

When Nginx serves a PHP application, the 500 response often originates in the application rather than in Nginx. Nginx hands the request to PHP-FPM over a socket, and when PHP-FPM returns a 500 response, Nginx normally passes that status to the browser. The Nginx error log may capture FastCGI output or a transport failure, while details such as the file, line, and exception are usually in the PHP error log.

If the failing page shows a bare error with a line such as nginx/1.24.0 (Ubuntu) printed underneath, that footer comes from the Nginx default error page. It confirms that Nginx served the error page and identifies the build, but it says nothing about the cause. Setting server_tokens off; in the http block removes the version and build information from error pages and the Server response header, although the Nginx name remains.

Start with the PHP-FPM log. On Ubuntu and Debian the path includes the PHP version:

Terminal
sudo tail -50 /var/log/php8.3-fpm.log

On Fedora, RHEL, and derivatives, PHP-FPM writes to its own directory:

Terminal
sudo tail -50 /var/log/php-fpm/www-error.log

An empty PHP-FPM log does not mean there was no error. PHP may be writing to another configured destination, or worker output may not be captured. The next section shows how to check both settings.

Nginx does return a 500 on its own in two cases worth knowing. The first is a rewrite loop, where a try_files or rewrite directive keeps sending the request back to itself. The error log names it directly:

output
rewrite or internal redirection cycle while internally redirecting to "/index.php"

The second is a failure to write temporary files. When the buffer directories under /var/lib/nginx or /var/cache/nginx are not writable by the Nginx worker user, buffering the upstream response fails and the request ends in a 500.

Before restarting Nginx, test the configuration:

Terminal
sudo nginx -t

A valid configuration produces:

output
nginx: the configuration file /etc/nginx/nginx.conf syntax is ok
nginx: configuration file /etc/nginx/nginx.conf test is successful

If the test passes, Nginx has valid syntax and can open the files referenced by the configuration. It does not rule out runtime problems such as rewrite cycles, incorrect upstream settings, or worker permission failures. Reproduce the request and examine both the Nginx and application logs. Lowering the severity level on the Nginx error log from the default error to info records more of the exchange with the upstream. The debug level shows everything, but it is only available when Nginx was compiled with --with-debug, which you can confirm in the output of nginx -V.

Database Connection Failure

Web applications that rely on a database (MySQL, MariaDB, PostgreSQL) return a 500 error if they cannot connect. This can happen when the database service is down, credentials are wrong, or the database is corrupted.

Check whether the database service is running:

Terminal
sudo systemctl status mysql

If it is not running, start it:

Terminal
sudo systemctl start mysql

Verify the database credentials in your application configuration file (e.g., wp-config.php for WordPress).

Broken Plugins or Themes

Content management systems like WordPress, Joomla, and Drupal can throw a 500 error after updating or installing a plugin or theme.

To diagnose, rename the plugins directory to disable all plugins at once:

Terminal
sudo mv /var/www/html/wp-content/plugins /var/www/html/wp-content/plugins.bak
Warning
This takes down every plugin on a live site at once, including caching, security, and payment plugins. Run it during a maintenance window, or copy the site to a staging environment and test there.

If the site loads, re-enable plugins one at a time to find the one causing the error.

Server Resource Exhaustion

Running out of memory or disk space causes the server to fail when processing requests. Check available memory and disk space:

Terminal
free -h
Terminal
df -h

If memory is exhausted, identify the processes consuming the most memory:

Terminal
ps aux --sort=-%mem | head -10

If disk space is full, find and remove large unnecessary files, or clear log files that have grown too large.

Incorrect File Ownership After Deployment

After deploying files via SCP , rsync, or Git, the uploaded files may be owned by the wrong user. The web server process cannot read files it does not own.

Check the ownership:

Terminal
ls -la /var/www/html/

Fix it by setting the correct owner:

Terminal
sudo chown -R www-data:www-data /var/www/html

On Fedora, RHEL, and derivatives, correct ownership is not always enough. SELinux labels every file with a security context, and files copied into the web root from a home directory or unpacked from an archive usually keep the wrong label. First check whether SELinux is enforcing:

Terminal
getenforce

If the output is Enforcing, restore the expected context on the web root:

Terminal
sudo restorecon -Rv /var/www/html

SELinux records denials in the audit log rather than the web server log, which is why the cause can stay invisible. List the recent ones with:

Terminal
sudo ausearch -m avc -ts recent

Depending on what was blocked, a denial surfaces as either a 403 or a 500. Applications that open outbound connections, to a remote database or an external API, need that permission granted explicitly:

Terminal
sudo setsebool -P httpd_can_network_connect on

Checking Server Logs

The fastest way to determine the cause of a 500 error is to check the web server error log. The log file location depends on your distribution and web server:

ServiceLog Path
Apache (Ubuntu, Debian)/var/log/apache2/error.log
Apache (Fedora, RHEL)/var/log/httpd/error_log
Nginx/var/log/nginx/error.log
PHP-FPM (Ubuntu, Debian)/var/log/php8.3-fpm.log
PHP-FPM (Fedora, RHEL)/var/log/php-fpm/www-error.log

On an Nginx and PHP-FPM stack, check both. The Nginx log records proxy and transport failures and may capture FastCGI output, while the PHP log usually contains the application error. If a log file is missing or was redirected to the journal, read it through journalctl instead:

Terminal
sudo journalctl -u php8.3-fpm -n 50

To view the most recent entries:

Terminal
sudo tail -50 /var/log/nginx/error.log

For real-time monitoring while you reproduce the error:

Terminal
sudo tail -f /var/log/nginx/error.log

The log typically contains the exact error message, the file path, and the line number that caused the failure. If you want to send each site to its own file or change the severity level, our guide on configuring the Nginx logs covers the error_log directive in detail.

Finding the Real Error Message

A 500 error with an empty log is the most frustrating version of this problem. The server reports a failure, the browser shows a generic page, and nothing in /var/log/nginx/error.log explains what happened. The application may be writing to a different log, or PHP-FPM may not be capturing worker output. Checking the active FPM configuration and logging destination makes the error visible.

Start by locating the configuration file loaded by PHP-FPM rather than PHP CLI. On Ubuntu and Debian, run the versioned FPM binary, replacing 8.3 with your installed PHP version:

Terminal
sudo php-fpm8.3 -i | grep 'Loaded Configuration File'

On Fedora, RHEL, and derivatives, use the unversioned binary:

Terminal
sudo php-fpm -i | grep 'Loaded Configuration File'

Edit the file shown in the output and confirm that PHP records errors without displaying them to visitors:

ini
log_errors = On
error_reporting = E_ALL
display_errors = Off

Leave the distribution’s existing error_log destination in place. If you configure a custom path, create the file first and make it writable by the PHP-FPM pool user. Printing the error text in the browser exposes file paths, query fragments, and configuration details to every visitor, and the log gives you the same information without that risk. Our PHP error reporting guide walks through these directives and the values to use in production.

PHP-FPM sends worker standard output and error streams to /dev/null by default. Enable their capture in the pool configuration, found at /etc/php/8.3/fpm/pool.d/www.conf on Ubuntu and Debian and at /etc/php-fpm.d/www.conf on Fedora and RHEL. Keep any existing php_admin_value[error_log] setting:

/etc/php/8.3/fpm/pool.d/www.confini
catch_workers_output = yes
php_admin_flag[log_errors] = on

On Ubuntu and Debian, reload the versioned PHP-FPM service so the pool picks up the change:

Terminal
sudo systemctl reload php8.3-fpm

On Fedora, RHEL, and derivatives, reload the unversioned service:

Terminal
sudo systemctl reload php-fpm

WordPress adds a layer of its own and hides fatal errors behind a generic message. A standard wp-config.php already defines WP_DEBUG as false. Change that existing value to true instead of adding a second definition, then add the other two constants before the comment that marks the end of the editable section. The resulting block should look like this:

wp-config.phpphp
define( 'WP_DEBUG', true );
define( 'WP_DEBUG_LOG', true );
define( 'WP_DEBUG_DISPLAY', false );

Errors then land in wp-content/debug.log. Once you have found the problem, change WP_DEBUG back to false and remove the WP_DEBUG_LOG and WP_DEBUG_DISPLAY lines. A debug log left enabled on a live site keeps growing and records details about the installation that should not be readable.

With logging in place, tail the distribution’s PHP-FPM log and reload the failing page in your browser. On Ubuntu and Debian, replace 8.3 with the installed PHP version:

Terminal
sudo tail -f /var/log/php8.3-fpm.log

On Fedora, RHEL, and derivatives, follow the default pool error log:

Terminal
sudo tail -f /var/log/php-fpm/www-error.log

The entry that appears at the moment the page fails usually identifies the cause. Compare its timestamp and request path with the failing request so that unrelated background errors do not distract you.

Troubleshooting

500 appears after a deployment
Check ownership and permissions under the web root. Deployment tools often write files with the wrong user. Use ls -la to verify owner/group and correct them with chown and safe file/directory modes.

500 appears only on dynamic pages
This usually points to PHP or application-level failures. Check web server logs and PHP-FPM logs, then verify extensions, memory limits, and application configuration values.

500 appears after editing .htaccess
Temporarily rename .htaccess and test again. If the site starts working, restore the file and fix directives one section at a time.

500 appears after a configuration change
Run sudo nginx -t or sudo apachectl configtest, which report the file and line of a bad directive. A passing test rules out syntax errors, but runtime configuration problems such as rewrite loops, upstream settings, and permissions can still cause a 500 response.

No clear error in web server log
Enable more detailed application logging and reproduce the error while tailing logs in real time (tail -f). Also check service status with systemctl status for the web server, PHP-FPM, and database.

FAQ

Is a 500 error my fault as a visitor?
No. A 500 error is a server-side issue. There is nothing wrong with your browser, device, or internet connection. The server administrator needs to fix it.

What is the difference between 500, 502, and 503 errors?
A 500 error means the server encountered an unexpected condition. A 502 (Bad Gateway) means a reverse proxy received an invalid response from an upstream server. A 503 (Service Unavailable) means the server is temporarily overloaded or under maintenance.

How do I fix a 500 error in WordPress?
The most common causes are a broken plugin, a corrupted .htaccess file, or a PHP memory limit. Rename the plugins directory to disable all plugins, rename .htaccess to regenerate it, and increase the memory_limit in php.ini. If the page is blank instead of showing an error, follow our guide on fixing the WordPress White Screen of Death .

Why does Nginx return 500 instead of 502?
The two codes point at different layers. Nginx returns a 502 when it cannot reach the upstream at all, for example when PHP-FPM is stopped or the socket path in fastcgi_pass is wrong. It returns a 500 when the upstream was reached and answered with an error, which almost always means PHP ran and threw a fatal error. A 502 sends you to the service status, and a 500 sends you to the application log.

Can a 500 error be caused by too much traffic?
Yes. If the server runs out of memory or worker processes due to high traffic, it returns a 500 error. Increasing server resources, enabling caching, or using a CDN can help.

How do I prevent 500 errors?
Monitor server logs regularly, set up alerts for error spikes, test changes in a staging environment before deploying to production, and keep software and dependencies up to date.

Conclusion

A 500 Internal Server Error means the server encountered a problem it could not handle. The most common causes are file permission issues, .htaccess errors, PHP failures, and database connection problems. Always check the web server error log first; it contains the specific error that triggered the 500 response.

Linuxize Weekly Newsletter

A quick weekly roundup of new tutorials, news, and tips.

About the authors

Dejan Panovski

Dejan Panovski

Dejan Panovski is the founder of Linuxize, an RHCSA-certified Linux system administrator and DevOps engineer based in Skopje, Macedonia. Author of 1000+ Linux tutorials with 20+ years of experience turning complex Linux tasks into clear, reliable guides.

View author page