Laravel 500 Error After Deployment: 6 Steps to Fix It

Fix a Laravel 500 error after deployment in 6 steps: read the log, check the public folder, permissions, app key, caches and PHP version.

By Rodney Lungayan5 min read

Server rack with a warning sign, showing a Laravel 500 error after deployment

Your Laravel app worked on your laptop. You deployed it, opened the site, and now you see a plain white page with "500 | Server Error". A Laravel 500 error after deployment feels vague, but it almost always comes from a short list of causes. This guide gives you the order I check them in.

The fix at a glance: read the log first, then check the document root, folder permissions, the app key, stale caches and the PHP version. Most deployments are fixed by step 3 or 4.

All commands and settings below come from the current Laravel 13.x deployment guide. If your app runs an older Laravel version, open the docs for that version before you change anything.

1. Read the log behind your Laravel 500 error

A 500 error is a general message. The real reason is written to your log. Laravel's default log channel is stack, and the single channel in the logging documentation writes to storage/logs/laravel.log. Open the last 50 lines of that file and look for the first error message, not the long list of lines under it.

It is tempting to set APP_DEBUG=true to see the error on screen. Please don't do this on a live site. The Laravel docs say it should always be false in production, because debug mode can show private configuration values to your visitors. The log gives you the same answer without the risk.

If the log file does not exist or stays empty, that is a clue too. It usually points to step 2 or step 3: the app is not starting, or it cannot write its log.

2. Check that the web server points to the public folder

Laravel must be served from its public/ folder, and every request must go to public/index.php. The deployment guide warns that you should never move index.php to the project root, because that can expose sensitive files to the internet.

On Nginx, the setting looks like this (use your own path):

root /srv/example.com/public;

location / {
    try_files $uri $uri/ /index.php?$query_string;
}

On shared hosting, this is the "document root" setting in your hosting panel. If it points at the project folder instead of public, fix it there. A wrong root often shows up as a 403, a 404 or a 500, depending on the server.

3. Fix folder permissions on storage and bootstrap/cache

Laravel writes logs, sessions, compiled views and cache files while it runs. The docs say the web server process owner needs write access to the bootstrap/cache and storage folders.

A typical log message here says "failed to open stream: Permission denied". Ask your host, or check in your server panel, which user runs PHP. Then make sure that user owns, or can write to, those two folders. Avoid chmod 777 as a quick fix. It opens the folders to every user on the server.

4. Confirm the app key is set

Laravel's encrypter needs the APP_KEY value. The encryption documentation says to generate it with php artisan key:generate, and that it is normally created for you when you install Laravel. If you copied the project to a new server without the .env file, the key may be missing. The error in the log then reads "No application encryption key has been specified".

Be careful here. If your app already has users, do not generate a new key just to clear the error. The same page explains that changing the key logs out all sessions and makes older encrypted data unreadable. Copy the original APP_KEY from your old environment instead. If you must rotate it, the docs describe the APP_PREVIOUS_KEYS setting for that.

5. Clear stale caches, then rebuild them

Old cached files are a common reason a fix "does not work". Clear everything with one command:

php artisan optimize:clear

Test the site. If it loads, rebuild the caches the way the deployment guide recommends:

php artisan optimize

There is one trap to know about. After config:cache, Laravel no longer loads your .env file, and calls to env() outside the config files return null, as the configuration documentation explains. If your app works with a cleared cache but breaks with a cached one, search your code for env( calls outside the config folder and move them into a config file. Then read the value with config('...').

6. Check the PHP version and extensions

Laravel 13.x needs PHP 8.3 or higher. It also needs these extensions: Ctype, cURL, DOM, Fileinfo, Filter, Hash, Mbstring, OpenSSL, PCRE, PDO, Session, Tokenizer and XML. A server running an older PHP, or missing one extension, can fail before Laravel writes anything to the log.

You can see the PHP version and loaded extensions in your hosting panel, or by running php -v and php -m in a terminal on the server. Make sure the command-line version matches the version your website uses. They are sometimes different.

A quick test: the health route

Laravel 13.x includes a health route at /up by default. It returns a 200 response when the app starts without errors, and a 500 when it does not. Open /up on your site after each step. It tells you quickly whether the app boots at all, before you test your own pages.

When to get help

Ask for help if the log shows a database or server-level error you cannot trace, if the host does not let you change the document root or permissions, or if the site holds live customer data and you are unsure what is safe to change. Share the first error line from the log (without passwords or keys) with your host or developer. It saves everyone time.

If you would like a developer to set up or rescue a Laravel deployment, see my Laravel web app development service or get in touch. If your site runs on WordPress instead, the same log-first habit applies to a WordPress 503 error.

Work with me

Have a project in mind? Let's build it together.

I'm Rodney Lungayan, a full stack developer who builds fast, secure WordPress websites and custom front-ends. If this article helped, imagine what we can do on your project.

Hire me for your project See my work