
4 minutes read
The "419 Page Expired" error; 5 quick fixes
Introduction to the 419 error in Laravel
Ever hit that irritating “419 Page Expired” error in your Laravel app? You’re definitely not alone. This error regularly disrupts form submissions, logins, and other POST requests. It usually relates directly to Laravel’s CSRF (Cross-Site Request Forgery) token system or session management.
Here’s exactly why this happens and how to fix it.
Why the 419 error occurs
The Laravel framework relies heavily on CSRF tokens to protect your application from malicious cross-site requests. Whenever you create a form, you’ll typically use the @csrf
directive, which inserts a hidden input containing a unique CSRF token:
<form method="POST" action="/submit"> @csrf … </form>
This generates:
<input type="hidden" name="_token" value="unique_token_here" />
This token ensures your form submissions originate legitimately from your site. However, the 419 error happens when there’s a mismatch or missing token due to:
1. Expired CSRF tokens
If you keep your form open too long (like on a login page) because you went AFAIK to get some coffee, the CSRF token can expire, triggering the error when you submit.
2. Missing @csrf
directive
Forgetting the directive will always cause this issue:
<!-- Incorrect; missing @csrf directive. --> <form method="POST" action="/submit"> … </form>
3. Expired Laravel sessions
Session expiration invalidates the token as it’s tied to your session. Losing the session means losing the token.
4. Incorrect session or cookie configurations
Misconfigured session settings or incorrect cookie policies can cause unexpected CSRF token mismatches.
5. Browser cache and cookie conflicts
Old or conflicting browser cookies and cached sessions might trigger the error.
5 quick solutions to fix the 419 error
1. Include the @csrf
directive
Always use it in every form:
<form method="POST" action="/submit"> @csrf … </form>
2. Refresh the form page
If you’ve been idle too long, just refresh your browser to get a fresh token. It’s that simple and it works like by design.
3. Verify and update session settings
Check your session lifetime and cookie settings in config/session.php
:
'lifetime' => env('SESSION_LIFETIME', 120), // Minutes. 'expire_on_close' => false, 'secure' => env('SESSION_SECURE_COOKIE', true), 'same_site' => 'lax', // Can be "strict", "lax", or "none". 'http_only' => true,
Set a reasonable session lifetime and ensure it aligns with your needs.
4. Clear your browser cache and cookies
Sometimes the easiest solution is simply clearing browser data or testing in incognito/private mode.
5. Ensure your web server configuration handles Laravel sessions properly
If you’re using Apache or Nginx, confirm your server correctly manages cookies and PHP sessions.
For Apache, ensure your .htaccess
or virtual host configuration properly forwards requests:
<IfModule mod_rewrite.c> RewriteEngine On RewriteRule ^(.*)$ public/$1 [L] </IfModule>
For Nginx, typical Laravel configuration looks like:
location / { try_files $uri $uri/ /index.php?$query_string; }
Handling AJAX requests properly
When making AJAX or API requests, always include the CSRF token in your request headers:
<meta name="csrf-token" content="{{ csrf_token() }}" />
fetch('/submit', { method: 'POST', headers: { 'Content-Type': 'application/json', 'X-CSRF-TOKEN': document.querySelector('meta[name="csrf-token"]').content }, body: JSON.stringify({ /* … */ }) });
Temporarily disabling CSRF protection (use cautiously!)
Only use this approach rarely and sparingly. Disabling CSRF protection selectively by editing app/Http/Middleware/VerifyCsrfToken.php
:
namespace App\Http\Middleware; use Illuminate\Foundation\Http\Middleware\VerifyCsrfToken as Middleware; class VerifyCsrfToken extends Middleware { protected $except = [ '/some-webhook-endpoint', ]; }
Warning: Never fully remove CSRF middleware as it significantly weakens your application’s security.
Best practices to prevent future 419 errors
- Regularly verify your forms include the
@csrf
directive. - Keep session lifetimes aligned with typical user interactions so they don’t hit the error while they went to the toilets.
- Regularly clear browser caches during testing phases.
- Maintain consistent session and cookie settings in production environments.
Additional troubleshooting tips
- Use Laravel’s Artisan CLI commands to clear persistent cache or config issues:
php artisan cache:clear php artisan config:clear php artisan view:clear
- Quickly test session handling on your server:
Route::get('/session-test', function () { session(['test' => 'it works!']); return session('test'); });
- Review Laravel’s error logs in
storage/logs/laravel.log
Conclusion
The Laravel 419 error, while frustrating, is easily fixable. Follow these straightforward tips and you’ll eliminate this headache, ensuring smoother experiences for you and your users.
For deeper insights, refer to the official CSRF protection documentation.
Did you like this article? Then, keep learning:
- Related Laravel error fix deepening troubleshooting knowledge
- Add Alpine.js to enhance Laravel frontend interactivity
- Learn how to clear Laravel's cache, complementing session fixes
- Explore Laravel middleware customization relevant to CSRF middleware
- Understand Laravel's error handling for robust HTTP requests
- Understand Laravel basics to contextualize CSRF token workings
- Upgrade guides to keep Laravel projects updated and secure
- Upgrade guides continue, useful for Laravel CSRF updates
- Discover Laravel security best practices related to CSRF protection
- Learn Artisan, useful for cache clearing and debugging Laravel apps
12 comments
Thanks. 419 issue resolved after adding /login page in protected list of VerifyCsrfToken
That's great, but I don't recommend that. A login page must be secure. 🙂
ok. got you. Seems to be a necessary evil.
@BenjaminCrozat - I wonder what the best practice is for reducing 419 on login pages. I'm using L11 JetStream (rip) default scaffolding and experience this. Seems like refreshing the csrf token with JS in browser might be only solution... wonder if this get's solved in L12/StarterKits
Sorry for the late reply! This hasn't been solved. You can increase the session's lifetime, though. I updated the article since you commented.
I'm facing same 419 page expired issue but mine is a Laravel 11 API, I'm using postman and understand I have to make a pre-request to /sanctum/csrf-token for the x-xsrf-token, but that request returns an empty response and I'm not sure what to try now. the documentation does not touch on this for APIs.
Have you tried following the documentation from the start again? I find it weird that
/sanctum/csrf-token
has no effect. What's the HTTP code? 419 there too?Also, when you run
php artisan route:list
you will see which controller is associated with/sanctum/csrf-token
. Maybe put add()
there. That's how you make sure you're actually hitting the route.What if the 419 appears just for me? All my colleagues can log in from theirs house's, but I can't even though I have restarted my network modem...
This error has nothing to do with your location or your network. 🙂
There might be something related to your cookies, your browser possibly restricts cookies.
As Benjamin said:
So, please check your browser configuration and see if there's something odd, or try to delete the old cookie, this might solve your problem.
Hi @Benjamin, how we replace the error page 419 with notification? I want make the error popup more nice than default laravel error page.
Never thought about doing that. Worth asking ChatGPT because I have no idea where to start.