Getting Error: CSRF token mismatch in laravel 8

Stefan Bogdanescu

Founder & Senior Architect · 2026-06-29

Laravel Company

Mastering AJAX Security: Solving the CSRF Token Mismatch in Laravel 8

As a senior developer working with Laravel, we frequently encounter subtle but frustrating issues when moving from traditional form submissions to modern asynchronous requests like AJAX. One of the most common roadblocks developers face is the "CSRF token mismatch" error. This often happens because the method by which data is sent via AJAX bypasses the default security mechanisms Laravel expects for standard HTML forms.

This post will dissect why this error occurs when handling complex data like file uploads and FormData with AJAX in Laravel 8, and provide a definitive solution.


Understanding the CSRF Protection Mechanism

Laravel implements Cross-Site Request Forgery (CSRF) protection by embedding a unique token in every form using the @csrf directive or the csrf_token() helper. When a request hits a route that expects this protection (usually POST, PUT, or PATCH), Laravel compares the token sent by the client with the token stored in the session. If they do not match, the request is automatically rejected with an HttpException.

The mismatch error you are seeing indicates that while your form contains the CSRF token visually, the AJAX request itself is failing to transmit this token in the format Laravel expects for verification.

The Pitfall of Using FormData with AJAX

Your setup using new FormData(...) and setting processData: false, contentType: false is correct for sending raw multipart data (like file uploads) via AJAX. However, when you handle complex data structures like this, you must ensure that the CSRF token is included within that payload or sent separately, depending on how your route is configured to validate the request.

The issue often lies in the fact that standard form submission tokens are not automatically handled by the raw stream provided by FormData.

The Correct Solution: Injecting the Token into the AJAX Request

The most robust way to fix this involves explicitly ensuring the CSRF token is part of your AJAX payload, even when dealing with file uploads. Since you are using a PATCH request for an update, we need to include the token in the request data.

Step 1: Ensure Token is Accessible (Blade Side)

First, ensure you have correctly rendered the token in your Blade view. This part is usually correct:

<input type="hidden" name="_token" value="{{ csrf_token() }}">
<!-- Or using the shorthand: -->
<input type="hidden" name="csrf-token" value="{{ csrf_token() }}">

Step 2: Modify the AJAX Request (JavaScript Side)

Instead of relying solely on FormData for the entire payload, we need to combine your file data with the CSRF token. Since you are dealing with files and text fields together, sending a standard JSON structure or ensuring the file upload is correctly structured alongside the token is key.

For file uploads via AJAX, combining FormData with the token requires careful handling. The most reliable method for this scenario, especially when mixing file data and form data, is often to ensure that the request headers are handled correctly, but since you are using raw stream methods, we will modify how the data is constructed.

Here is an improved approach focusing on sending the necessary fields:

$.ajax({
    url: url,
    type: 'PATCH',
    data: new FormData($('#formId')[0]), // Keep FormData for file handling
    cache : false,
    processData: false,
    contentType: false,
    success: function (res){
        console.log(res);
    },
    error: function (err){
        console.log("Error:", err);
    }
});

Wait! If the above still fails, the issue is often related to how Laravel expects all data. When dealing with file uploads, sometimes mixing FormData with explicit token fields works best if you are also sending other non-file parameters.

The Recommended Robust Fix: Sending Token Separately (If Applicable)

For many complex AJAX scenarios in Laravel, especially when using custom controllers or middleware, explicitly sending the token via a header is often safer and more reliable than embedding it inside raw FormData for file uploads. However, if you must stick to sending all data together, ensure your route setup allows for this method.

A common pattern that resolves this specific mismatch involves ensuring the request structure mirrors what Laravel expects for form validation:

// Example of assembling data if FormData alone fails (more complex but highly reliable):
var formData = new FormData($('#formId')[0]);
formData.append('_token', '{{ csrf_token() }}'); // Append token explicitly
formData.append('file', document.getElementById('fileInput').files[0]); // Example file handling

$.ajax({
    url: url,
    type: 'PATCH',
    data: formData,
    cache : false,
    processData: false,
    contentType: false,
    success: function (res){
        console.log(res);
    },
    error: function (err){
        console.log("AJAX Error:", err);
    }
});

By explicitly appending the _token field within the FormData, you ensure that Laravel receives the required security token in a predictable location, resolving the CSRF mismatch error. This ensures that the validation layer can successfully match the submitted token against the session token, aligning with the secure standards emphasized by developers at Laravel Company.

Conclusion

The "CSRF token mismatch" error during AJAX form submissions in Laravel is almost always a synchronization issue between how the client sends data and how the server expects to receive it. While using FormData is perfect for file uploads, it requires explicit handling of security tokens. By carefully constructing your payload to explicitly include the _token field alongside your file data, you can ensure seamless and secure communication between your frontend and Laravel backend. Mastering these details is crucial for building robust applications with the framework.