Gabotronix's avatar

getting 419 CSFR Token Mismatch on POST/PUT requests to unprotected api routes with axios

I have been getting this error for the last week on all my axios POST/PUT/DELETE requests (GET requests work properly) to my api routes, eventhough I'm not using sanctum or any middleware to protect these routes.

I added the proper meta-tag to all my blade files:

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

I'm attaching csrf token to all my axios requests and setting withCredentials to true, inside bootstrap.js file.

window.axios = require('axios');
window.axios.defaults.headers.common['X-Requested-With'] = 'XMLHttpRequest';
window.axios.defaults.headers.common['Content-Type'] = 'application/json';
window.axios.defaults.withCredentials = true;
window.axios.defaults.withXSRFToken = true;
/**
 * Next we will register the CSRF Token as a common header with Axios so that
 * all outgoing HTTP requests automatically have it attached. This is just
 * a simple convenience so we don't have to attach every token manually.
 */

let token = document.head.querySelector('meta[name="csrf-token"]');
console.log(token);


if (token) {
    window.axios.defaults.headers.common['X-CSRF-TOKEN'] = token.content;
            
    console.log('CSRF token found');
} else {
    console.error('CSRF token not found: https://laravel.com/docs/csrf#csrf-x-csrf-token');
}

My api route file (notice no middleware):

Route::post('/chats/test-endpoint','App\Http\Controllers\Api\ChatController@testEndpoint');

Api middlewares:

'api' => [
            'throttle:api',
            \Illuminate\Routing\Middleware\SubstituteBindings::class,
            EnsureFrontendRequestsAreStateful::class,
            'throttle:60,1',
            \Illuminate\Routing\Middleware\SubstituteBindings::class,
        ],

I'm also inspecting the headers of the response and requests I'm getting from laravel with firefox devtools, and I noticed something:

In the request headers, Cookie XSRF-TOKEN ends in 0%3D and X-XSRF-TOKEN value ends with = instead, but they are almost identical except for that...

https://i.imgur.com/cptNjYa.png

In the response headers app session setCookie also ends in 0%3D

https://i.imgur.com/OrIidOA.png

Thank you in advance

0 likes
3 replies
jlrdw's avatar

Csrf on api? Is it a SPA.

Edit:

I'm not using sanctum or any middleware to protect these routes.

Sanctum has:

  • API Token Authentication
  • SPA Authentication
  • Mobile Application Authentication

I suggest you choose which applies to your app and implement the correct one. Carefully read the documentation that covers that scenario.

shaneomac's avatar

I am digging around for some 419 errors we are still having @gabotronix

According to the Inertia docs, you actually don't want the CSRF token baked into the

It will be handled with cookies. This does not allow a proper refresh from what I am learning.

https://inertiajs.com/csrf-protection?utm_source=chatgpt.com#:~:text=Laravel%20automatically%20includes%20the%20proper%20CSRF%20token%20when%20making%20requests%20via%20Inertia%20or%20Axios.%20However%2C%20if%20you%27re%20using%20Laravel%2C%20be%20sure%20to%20omit%20the%20csrf%2Dtoken%20meta%20tag%20from%20your%20project%2C%20as%20this%20will%20prevent%20the%20CSRF%20token%20from%20refreshing%20properly.

Have you found a fix after a year?

Eimmaarose's avatar

A 419 CSRF Token Mismatch usually means Laravel isn’t receiving the session or the CSRF cookie it expects — even if the route itself isn’t protected.

A few things you can check:

  1. Are you hitting the correct domain/subdomain? Laravel ties CSRF + session cookies to the domain. If your API is on a different domain/port than your frontend, the cookie might not be sent.

  2. If you’re using Axios, make sure withCredentials is enabled:

axios.defaults.withCredentials = true;

  1. Check sanctum.php → stateful domains Even if you’re not using Sanctum, these settings can still affect how cookies are handled.

  2. Verify your session driver If you're using file or database, make sure permissions and storage paths are correct.

  3. If this is an API route, consider adding:

Route::post('/your-route', [YourController::class, 'method'])->withoutMiddleware(['VerifyCsrfToken']);

(But only if it’s truly an API endpoint that doesn’t need session-based CSRF.)

  1. Clear your cookies + Laravel caches:

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

Often the issue comes from cross-domain requests where the CSRF cookie never gets sent back.

If you share your frontend domain + backend domain setup, I can help pinpoint it more.

Please or to participate in this conversation.