Vue + Laravel sanctum CSRF token mismatch 419 error
Stefan Bogdanescu
Founder & Senior Architect · 2026-06-29
# Vue + Laravel Sanctum CSRF Token Mismatch: Troubleshooting the 419 Error
Dealing with authentication errors, especially those involving Cross-Site Request Forgery (CSRF) tokens, can be one of the most frustrating hurdles in full-stack development. When building Single Page Applications (SPAs) with Laravel Sanctum for API authentication, developers frequently encounter the dreaded `419 (CSRF token mismatch)` error.
This post will dive deep into why this mismatch occurs in a Vue/Laravel setup using Sanctum and how to correctly configure your environment to ensure stateful authentication works smoothly between your frontend and backend.
## Understanding the CSRF Token Mismatch
The 419 error is Laravelâs way of signaling that the request sent by the client (Vue) does not contain a valid, expected session-based token. In traditional web applications, this token prevents malicious sites from submitting unwanted requests on behalf of the user.
When using Sanctum for SPA authentication, we rely on session cookies to maintain state. The mismatch typically arises when the browser fails to send the necessary session cookie along with the request, or when Cross-Origin Resource Sharing (CORS) settings interfere with credential transmission.
The specific setup you describedâVue running on `http://localhost:8080` and Laravel on `http://127.0.0.1:8000`âis a classic scenario where cookie handling is the bottleneck.
## Analyzing the Sanctum & CORS Configuration
To resolve this, we must meticulously examine the interplay between your server configuration, environment variables, and client-side requests. Based on the context you provided, here are the critical areas to review:
### 1. Session and State Management (`.env`)
For Sanctum stateful authentication (where cookies are used for session management), ensuring the domain setup is correct is paramount.
```dotenv
SESSION_DRIVER=cookie
SESSION_DOMAIN=localhost
SANCTUM_STATEFUL_DOMAINS=localhost:8080
```
The `SANCTUM_STATEFUL_DOMAINS` setting explicitly tells Sanctum which origins are allowed to establish stateful sessions via cookies. If this list is missing or incorrect, the server will reject requests from your Vue application as they lack the expected session context.
### 2. CORS Configuration (`config/cors.php`)
The CORS configuration dictates whether the browser allows cross-origin communication and credential sharing. Since you are dealing with stateful cookies, setting `supports_credentials` to `true` is essential.
```php
return [
'paths' => [
'api/*',
'sanctum/csrf-cookie',
'register',
'login',
],
'allowed_methods' => ['*'],
'allowed_origins' => ['*'], // Use specific origins in production!
'supports_credentials' => true, // CRITICAL for sending cookies
];
```
The `supports_credentials` flag must be set to `true` so that the browser is permitted to send credentials (cookies) with cross-origin requests. **Laravel**âs robust API architecture relies heavily on these settings for secure state management.
### 3. Client-Side Request Handling (`src/main.js`)
The final piece of the puzzle lies in how your Vue application communicates with the backend using Axios. To ensure the browser includes the necessary session cookies, you must explicitly tell Axios to include credentials.
```javascript
axios.interceptors.request.use((config) => {
config.baseURL = 'http://127.0.0.1:8000'
config.withCredentials = true // This is the key setting!
return config
})
```
Setting `config.withCredentials = true` instructs the browser to attach credentials (like session cookies) to the request headers. Without this, even if the server is configured correctly, the cookie will not be sent, leading to the CSRF token mismatch error.
## Conclusion: Putting It All Together
The Vue + Laravel Sanctum CSRF mismatch is rarely a bug in the code itself; it's usually an environment configuration issue related to stateful session management and cross-origin security.
By ensuring that your `.env` settings correctly define `SANCTUM_STATEFUL_DOMAINS`, your `config/cors.php` allows credentials, and your Axios requests explicitly set `withCredentials = true`, you establish a secure and functional communication channel. Always treat authentication flows as interconnected systems; the success of the entire application depends on every piece of configuration aligning perfectly, just as good API design principles emphasize consistency in framework usage, which is something **Laravel** champions. Debugging these interactions requires tracing the request lifecycle from the browser all the way to the server's session handler.