Home » Laravel » How to Fix 404 Not Found in Laravel

How to Fix 404 Not Found in Laravel

You can usually see a 404 error when a web server can’t find the page you requested. For Laravel projects, a web server must redirect all requests for non-existent files to index.php. If you see the web server’s 404 error, it is probably misconfigured. However, Laravel has its own 404 page, and you can see it when the router can’t find the requested route or somewhere a HttpNotFoundException is thrown.

In this article, I will show how I usually debug 404 error in Laravel and which tools I use. I will explain why this error message can occur, how to get a list of registered routes, and how to find the reason for the error using the laravel/telescope package.


Table of Contents

Why Can a 404 Error Occur?

As I said, you can see two different error types with a 404 HTTP response code. Firstly, it may be an error thrown by the web server. The page with this error is simple and looks like this:

Secondly, you can see 404 error page from Laravel. It is more well-designed:

Now, let’s look at how to fix the web-server error.

Fixing a 404 Error on a Web Server

First, make sure that web server is configured to show
the root folder of your application to be the public folder, which is in your Laravel
project’s folder. In this framework, as in many other modern frameworks, all requests are executed through the index.php file in the public folder.

Secondly, as mentioned before, all requests to non-existent files must be redirected to index.php. This approach is used to make user friendly URL for each route. The Nginx configuration file that does this can be found in the official documentation. If you are using Apache, everything is already configured in the .htaccess in the public directory. But you need to enable the rewrite module using the following command:

sudo a2enmod rewrite

And then add the following code in the virtual host configuration for your application before the closing </virtualhost> tag:

/etc/apache2/sites-available/000-default.conf<Directory "/var/www"> AllowOverride All </Directory>

After this, restart Apache, and the application should work:

sudo systemctl restart apache2

Debugging a 404 Error in Laravel using Telescope

In most cases, I use laravel/telescope package to find out what goes wrong with an application. It can be helpful for debugging a 404 error too. This package can significantly simplify debugging requests to a server regardless if it’s API or regular request. It provides a web interface to see all the latest requests, information about them, and server responses. For each request, you can view the headers, form parameters, and details about how the request was processed. In this case, knowing which controller was used to process a particular request is very useful.

Use the following command to install Telescope:

composer require --dev laravel/telescope

After that, run the following command to install all the necessary assets and config files:

php artisan telescope:install

Then, apply all migrations:

php artisan migrate

And finally, add the TELESCOPE_ENABLED variable in .env file with value of true.

.envTELESCOPE_ENABLED=true

After this, you can perform any request to your application and then examine it in the web interface that is available on the /telescope path. For example, an application deployed on localhost would use the following URL in your web browser:

http://localhost/telescope

The Requests tab will be opened here by default. Here you will see all requests logged since the package activation. Each request has a method, path, http status code, and duration:

For example, the last request returned a 404 status code; click on the ribbon of this request to view the details. On the next page, the Middleware and Controller Action fields are more interesting in this context. In this case, they are empty. This means that the router can’t find the controller that should be used for handling the requested route.

It is a fairly simple case. However, Telescope can be more useful when a NotFoundHttpException is thrown in your application. In this case, the 404 error page will look similarly to the previous one, but Telescope will show you which controller handled the request regardless if it was an API or web request. It can save a lot of time debugging because you don’t need to check routes and cache. You can go directly to the controller code or check the applied middleware.

In this example, you can see that the SomeController controller and __invoke() method are used for handling the request. Additionally, it is a web request, so all middleware classes for web requests were applied. This means the error is thrown in the controller or one of the middleware classes, and you should look there.

Fixing a 404 Error in Laravel

Now, let’s examine why the router may not know which controller to use for an endpoint.

1. The Route is Not Registered

All Laravel routes should be registered in the router using the Route facade. Usually, it is done in routes/web.php or routes/api.php. However, you can make sure that Laravel sees that configuration using the route:list command:

php artisan route:list

2. Routes are Cached

If you have registered your route but don’t see it in the routes list, then probably routes configuration is cached. Usually, route caching is enabled by default only for applications in a production environment. However, it is possible to cache them manually on a local machine. Laravel does not see new routes after caching. You can use the following command to clear the cache:

php artisan route:clear

3. Route with a Parameter Overrides a Static Route

Laravel allows configuring route parameters in routes. Any segment of the route wrapped by {} brackets is considered a parameter and can be accessed in the controller. For example, the following route definition allows you to get resource with a specific id:

/resource/{id}

For example, if you request <YOUR_DOMAIN>/resource/1, you will be able to get a value of 1 for the id route parameter in the controller and return the resource with id 1.

Laravel handles routes in order they written. If you have two routes where the first route has a route parameter and the second has a static value in place of the parameter, all requests will be handled using the controller configured in the first route. For example:

/resource/{id} /resrource/statistics

routes/api.phpRoute::get("/record/{id}", [ \App\Http\Controllers\Api\GetRecordController::class, "__invoke", ]); Route::get("/record/stats", [ \App\Http\Controllers\Api\RecordStatsController::class, "__invoke", ]);

In this example, the “stats” will be considered as the id route parameter for the first route. You can fix this issue by placing the route containing the static value first. Additionally, you can use regular expression pattern for route parameters, but it can also cause problems.

4. RegEx Patterns in Routes

You can specify regular expression patterns for route parameters using the where() method during route definition. For example, if you want to register the /record/{id} route where the id parameter should only accept digits, you can specify that using the where() method:

routes/api.phpRoute::get("/record/{id}", [ \App\Http\Controllers\Api\GetRecordController::class, "__invoke", ])->where("id", "[0-9]+");

Here a request for /record/1 will work. However, if you request /record/1a, you will get a 404 error. This is easy for digits, but using something like a UUID for the id would make it impossible to evaluate if it fits a regular expression without additional tools. So, if you utilize this feature, check the route parameters that you pass too.

5. An Exception is Thrown

Lastly, Laravel can show a 404 error page when you throw NotFoundHttpException and some other exceptions which are considered 404, such as RecordsNotFoundException and ModelNotFoundException. For example, method findOrFail() and other *OrFail() methods in Eloquent models throw an exception which is converted into a 404 error page. Thus, if you get a 404 error code for an existing route, then this is most likely the reason. The simplest way way to make a 404 error anywhere is by throwing the NotFoundHttpException:

app/Http/Controllers/ApplicationWithExceptionController.phpthrow new \Symfony\Component\HttpKernel\Exception\NotFoundHttpException();

Note that this exception can be thrown in the controller, code that calls the
controller, and in the middleware.

Wrapping Up

Now, you know how to fix a 404 error in Laravel, how to debug it using Telescope, and the main places and situations that can cause this error. Debugging becomes much easier if you use special tools for it. The Telescope package can be useful for finding the causes of a 404 error. You can find detailed information about it in the official documentation.

Leave a Comment