Fixed: Livewire "Snapshot Missing" Error After Session Timeout

The problem: A Livewire component throws a "Snapshot Missing" error whenever a user's session expires mid-interaction and they trigger any component action.

Environment: Laravel 11, Livewire 3.x, PHP 8.3, Redis/File session driver

The Error

● ● ●  response (419 / console)
Livewire\Exceptions\CorruptComponentPayloadException: Snapshot missing on Livewire component
    with id: "a8f3c21"

POST http://app.test/livewire/update 419 (unknown status)

Why It Happens

Livewire stores a "snapshot" of each component's state — its properties, checksum, and metadata — inside the request payload sent back to the server on every interaction. That snapshot is tied to the session that was active when the component was first rendered.

When the session expires (timeout, driver eviction, or the session cookie getting cleared), the server no longer recognizes the component's original context. Livewire can't validate the checksum against a session that no longer exists, so instead of a clean 419 redirect, it throws this corrupt-payload exception — because the snapshot itself references session data that's now gone.

This is especially common on pages left open in a browser tab for longer than session.lifetime, or on sites using a short session timeout for security reasons (banking-style admin panels, for example).

The Fix

You can't stop sessions from expiring, but you can catch the expiration gracefully and redirect the user instead of showing a raw exception. Livewire ships a built-in event for exactly this — hook into it on the frontend:

resources/views/layouts/app.blade.php
<script>
    document.addEventListener('livewire:init', () => {
        Livewire.hook('request', ({ fail }) => {
            fail(({ status, preventDefault }) => {
                if (status === 419) {
                    alert('Your session expired. The page will reload.');
                    window.location.reload();
                    preventDefault();
                }
            });
        });
    });
</script>

Then extend your session lifetime for pages where users tend to sit idle (form-heavy dashboards, long survey pages), rather than fighting the default:

.env
- SESSION_LIFETIME=120
+ SESSION_LIFETIME=480

If you're on Redis or another external session driver, also confirm the driver's own TTL isn't shorter than SESSION_LIFETIME — a mismatched Redis key expiry will cause this exact bug even with the config above set correctly.

Step-by-Step

  1. Add the livewire:init hook shown above to your main layout file (not per-component).
  2. Set preventDefault() inside the 419 check so Livewire doesn't also throw its default error to the console.
  3. Decide on a real session lifetime for your app's use case and update SESSION_LIFETIME in .env.
  4. If using Redis, run redis-cli CONFIG GET maxmemory-policy and confirm keys aren't being evicted early under memory pressure.
  5. Clear config cache after any .env change: php artisan config:clear.
  6. Test by manually expiring a session (delete the session cookie in DevTools) and triggering a Livewire action to confirm the reload prompt appears instead of the raw exception.

Edge case: If your app uses wire:poll for auto-refreshing components, a background tab can hit this error repeatedly while the user isn't even looking at the screen, spamming your error logs with false positives. Consider pausing polling with wire:poll.visible so it only runs while the tab is active — this cuts down noise significantly on dashboards.

Running into a different variant of this error? Get in touch via the Contact page and I'll help you trace it.

Advertisement
Advertisement