You’re debugging an API call and your HTTP client returns 419. You check the official IANA registry — it’s not there. You search MDN — nothing. What is HTTP 419, and why is your server sending it?
The short answer
HTTP 419 is not an official HTTP status code. It was never defined in any RFC or registered with IANA. It’s a custom status code used by specific frameworks — most notably Laravel (PHP) — to indicate that a CSRF token has expired or is missing.
If you’re seeing 419, your request either:
- Didn’t include a CSRF token at all, or
- Included a CSRF token that has expired (Laravel’s default is 120 minutes), or
- The session cookie was lost between requests
Where HTTP 419 comes from
Laravel defines this status code in its exception handler. When a POST, PUT, PATCH, or DELETE request hits a route protected by the VerifyCsrfToken middleware and the token is invalid, Laravel responds with:
HTTP/1.1 419 Page Expired
The “Page Expired” text is the default Laravel reason phrase for 419. It’s not describing a page — it’s describing the session state that the page’s CSRF token was tied to.
Other frameworks using 419
While Laravel is the most common source, some other PHP frameworks and custom APIs have adopted 419 for similar “session/token expired” semantics. It’s a de facto convention in the PHP ecosystem, not a universal standard.
How to fix HTTP 419
If you’re building a Laravel app
For browser forms (traditional rendering):
The most common cause is a session timeout. The user opens a form, walks away for two hours, and submits. The CSRF token was valid when the page loaded but the session has since expired.
Solutions:
- Extend the session lifetime in
config/session.php:
// Default is 120 minutes
'lifetime' => 480, // 8 hours
- Add client-side token refresh — on page load, make a lightweight AJAX request to get a fresh CSRF token:
<meta name="csrf-token" content="{{ csrf_token() }}">
// Refresh token every 30 minutes
setInterval(() => {
fetch('/api/csrf-token', {
headers: { 'X-Requested-With': 'XMLHttpRequest' }
}).then(r => r.json()).then(data => {
document.querySelector('meta[name="csrf-token"]').content = data.token;
});
}, 30 * 60 * 1000);
- Handle 419 gracefully on the client — catch the 419 response and redirect to login or refresh the page:
fetch('/api/save', { method: 'POST', body: formData })
.then(response => {
if (response.status === 419) {
// Session expired — reload to get fresh token
window.location.reload();
}
return response.json();
});
If you’re consuming a Laravel API
If you’re calling a Laravel API from a mobile app, SPA, or external service and getting 419:
-
Check your session/cookie handling. The API might expect session cookies. Make sure your HTTP client sends and receives cookies.
-
Use token-based auth instead. For API consumers, Laravel Sanctum or Laravel Passport tokens don’t have the same CSRF expiry problem. Use
Authorization: Bearer <token>headers instead of session cookies. -
Re-authenticate. If the session expired, the only fix is to log in again and get a fresh session.
If you’re a DevOps / infrastructure person
If you’re seeing 419 in your load balancer or API gateway logs:
- Check if the backend is Laravel. 419 is almost always Laravel CSRF.
- Check session storage. If Redis or the file-based session store is full or misconfigured, sessions may expire prematurely.
- Check clock sync. If your app servers have skewed clocks, session expiry calculations can be off.
How to check HTTP status codes
If you’re debugging API responses and need to quickly look up what a status code means, you can use a reference tool. Our HTTP status codes reference has all 63 official codes with descriptions and search.
Related status codes
| Code | Meaning | Relationship |
|---|---|---|
| 401 | Unauthorized | Missing or invalid authentication token |
| 403 | Forbidden | Authenticated but not permitted |
| 408 | Request Timeout | Server timed out waiting for the request |
| 419 | Page Expired | CSRF token expired (Laravel-specific) |
| 440 | Login Timeout | Another framework-specific variant |
| 503 | Service Unavailable | Server is down or overloaded |
The bottom line
HTTP 419 is Laravel telling you “your session expired, I can’t trust this request.” It’s not a bug — it’s a security feature working as designed. The fix is either extending the session lifetime, refreshing tokens client-side, or switching to API tokens for programmatic access.