Laravel file upload not parsed with "multipart/form-data"
Stefan Bogdanescu
Founder & Senior Architect · 2026-06-29
Fixing Laravel File Uploads: Understanding multipart/form-data
As a senior developer working with the Laravel ecosystem, Iâve seen countless developers encounter frustrating issues when dealing with file uploads. The scenario you are describingâwhere the form tag specifies enctype="multipart/form-data", yet the files are not parsed correctly in your controllerâis a very common point of confusion.
This post will diagnose why this happens, review your provided setup, and show you the robust, best-practice way to handle file uploads in Laravel.
The Mystery of multipart/form-data
The core of your issue lies in understanding how HTTP handles data transmission. When you upload a standard form (text inputs, checkboxes), the browser defaults to application/x-www-form-urlencoded. This format is designed for simple text data.
However, file uploads require transmitting both plain text form fields and binary file data. To handle this mixed contentâtext fields and raw file streamsâthe HTTP standard mandates the use of the multipart/form-data content type. This mechanism uses unique "boundaries" to separate each piece of data (each file, each text field) within a single request body.
Your HTML structure is correct:
<form action="{{ route('media.upload') }}" method="POST" enctype="multipart/form-data">
<!-- ... inputs ... -->
</form>This tells the browser to package the data correctly for file transfer. If Laravel isn't parsing it, the problem usually shifts from the frontend HTML to how the backend is expecting or handling the incoming stream of data.
Reviewing Your Laravel Implementation
Letâs look at your provided routes and controller structure:
Routes (web.php & api.php):
// web.php
Route::group(['middleware' => 'auth:api'], function () {
Route::get('upload', function () {
return view('upload');
})->name('upload');
});
// api.php
Route::post('upload', 'UploadController@upload')->name('media.upload');The routing structure is sound for a standard web application flow where a form submits to a controller endpoint.
Controller Function:
public function upload (Request $request)
{
dd($request->all());
}When you use dd($request->all()), the exact data Laravel receives from the request is displayed. If files are present, they should be available as parts of the request object. The fact that you see raw boundary information suggests that while the request arrived, the specific file payload isn't being mapped correctly to a standard UploadedFile object immediately upon retrieval, or there might be an issue with middleware interaction (like your auth:api).
The Correct Way to Handle File Uploads in Laravel
To reliably handle files in Laravel, you must use the Request object methods specifically designed for file handling. Do not rely solely on $request->all() for sensitive file data; use dedicated methods.
1. Ensure File Storage Configuration
Before anything else, ensure your storage disk is set up correctly in config/filesystems.php. You typically store uploaded files in the storage/app/public directory or a mounted disk.
2. Retrieving the File Correctly
When handling a file upload via a POST request, you retrieve the file using the file() method on the request object. The key is referencing the input name exactly as defined in your HTML (name="file").
Here is how your controller should be structured:
use Illuminate\Http\Request;
use Illuminate\Support\Facades\Storage;
class UploadController extends Controller
{
public function upload(Request $request)
{
// 1. Validate the presence of the file input
$request->validate([
'file' => 'required|file|max:10240', // Example validation
]);
// 2. Retrieve the uploaded file instance
// The key here ('file') must match the 'name' attribute in your HTML input tag.
if ($request->hasFile('file')) {
$file = $request->file('file');
// 3. Store the file on the disk (e.g., public storage)
// Using the storeAs method is a clean way to handle saving files.
$path = $file->store('uploads', 'public');
return response()->json(['message' => 'File uploaded successfully.', 'path' => $path], 200);
}
return response()->json(['error' => 'No file was uploaded.'], 400);
}
}By using $request->file('filename'), Laravel handles the complex parsing of the multipart/form-data stream and converts it into a manageable PHP UploadedFile object, making subsequent operations like validation and storage straightforward. This is the standard pattern recommended by the Laravel documentation for all file operations (you can find detailed guides on this at https://laravelcompany.com).
Conclusion
The failure to parse file uploads is rarely an issue with the HTML enctype. It is almost always a mismatch between how you access the data in your controller and the specific structure of the incoming multipart/form-data request. Always rely on Laravel's dedicated methods like $request->file('input_name') rather than trying to parse the entire raw array, ensuring your application remains robust and maintainable.