Solving 419 | Page Expired in Laravel

A 419 error means Laravel rejected a form submission because the CSRF token or session was invalid or expired. Below is a step-by-step guide to pinpoint and fix the root cause.


1. Ensure CSRF Token Is Present

In every <form> that submits to a POST, PUT, PATCH or DELETE route, include:

<form action="/..." method="POST">
  @csrf
  <!-- your inputs here -->
</form>

For AJAX requests, make sure you send the X-CSRF-TOKEN header. In JavaScript (e.g., Axios):

import axios from 'axios';

axios.defaults.headers.common['X-CSRF-TOKEN'] =
  document.querySelector('meta[name="csrf-token"]').getAttribute('content');

Also add the meta tag in your layout’s <head>:

<meta name="csrf-token" content="{{ csrf_token() }}">

2. Verify Session Configuration

Laravel uses cookies to store the session identifier. If sessions aren’t persisting, tokens expire immediately.

  • In config/session.php, check:
    • lifetime (minutes before expiry)
    • expire_on_close (whether to clear on browser close)
  • Ensure SESSION_DRIVER in your .env matches your setup (e.g., file, redis, database).
  • If you use Redis or Memcached, confirm connectivity and credentials.
SESSION_DRIVER=file
SESSION_LIFETIME=120

3. Check Cookie Domain & Secure Settings

Cookies have flags that can prevent them from being sent back to the server.

  • In config/session.php: 'domain' => env('SESSION_DOMAIN', null), 'secure' => env('SESSION_SECURE_COOKIE', false), 'same_site' => 'lax',
  • If you’re on https://, set SESSION_SECURE_COOKIE=true in .env.
  • For a subdomain or custom domain, set SESSION_DOMAIN=.yourdomain.com.

4. Clear and Rebuild Caches

Old configuration or view files can cause tokens to mismatch.

php artisan config:clear
php artisan route:clear
php artisan view:clear
php artisan cache:clear

If you’re using config caching in production, rebuild it:

php artisan config:cache

5. Confirm Middleware Order

In app/Http/Kernel.php, ensure \App\Http\Middleware\VerifyCsrfToken::class is registered under web middleware:

protected $middlewareGroups = [
    'web' => [
        \Illuminate\Session\Middleware\StartSession::class,
        \Illuminate\View\Middleware\ShareErrorsFromSession::class,
        \App\Http\Middleware\VerifyCsrfToken::class,
        // ...
    ],
];

The session must start before CSRF verification.


6. Debugging Tips

  • Use dd(session()->all()) or dd(csrf_token()) in a route to confirm you’re generating and persisting tokens.
  • Inspect browser dev-tools to see if the laravel_session cookie is set and sent on form submission.
  • For SPA frontends, consider using Laravel Sanctum or JWT instead of CSRF/session cookies.

Beyond 419: Improving UX

  • Implement AJAX form submission to catch token errors and auto-refresh the page or token.
  • Use Laravel Passport or Sanctum for API token auth, avoiding CSRF entirely for JSON APIs.
  • Shorten session lifetimes for increased security, but display a warning banner when a session is about to expire.

With these checks your forms will keep valid CSRF tokens, sessions will persist correctly, and 419 errors will vanish.

Leave a Reply