Benjamin Crozat “Heard about Sevalla? They let you deploy PHP apps with ease.” Claim $50 →

The "419 Page Expired" error; 5 quick fixes

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.

Misconfigured session settings or incorrect cookie policies can cause unexpected CSRF token mismatches.

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:

12 comments

  • nsubramkavin

    Thanks. 419 issue resolved after adding /login page in protected list of VerifyCsrfToken

    • Benjamin Crozat

      That's great, but I don't recommend that. A login page must be secure. 🙂

      • nsubramkavin

        ok. got you. Seems to be a necessary evil.

    • Elliot
      Elliot 4mos ago

      @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

      • Benjamin Crozat

        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.

  • jmakinin
    jmakinin 11mos ago

    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.

    • Benjamin Crozat

      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 a dd() there. That's how you make sure you're actually hitting the route.

  • Marcello Pato
    Marcello Pato 11mos ago

    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...

    • Benjamin Crozat

      This error has nothing to do with your location or your network. 🙂

    • Ayax Córdova
      Ayax Córdova 11mos ago

      There might be something related to your cookies, your browser possibly restricts cookies.

      As Benjamin said:

      This error has nothing to do with your location or your network

      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.

  • RICKY SUTANTO

    Hi @Benjamin, how we replace the error page 419 with notification? I want make the error popup more nice than default laravel error page.

    • Benjamin Crozat

      Never thought about doing that. Worth asking ChatGPT because I have no idea where to start.

Guest

Great deals for developers

Check all deals →