Skip to content

Fix Express + Multer returns Multipart - Boundary not found when uploading FormData from React Axios Step-by-Step Guide

The Multipart: Boundary not found error is a protocol-level failure that occurs when the Express backend (specifically the Multer middleware) expects a multipart/form-data payload but cannot find the unique delimiter string required to parse the stream.

In reactjs applications using Axios, this typically happens because the HTTP request header is manually set to multipart/form-data without the necessary boundary parameter. When you upload a file, the browser needs to generate a unique string (the boundary) to separate different parts of the form (e.g., text fields vs. binary files). If you hardcode the content type, you overwrite the browser’s ability to append this vital boundary identifier, leading to a total stack trace failure on the server.

Cause Technical Trigger Typical Scenario
Manual Header Definition Explicitly setting 'Content-Type': 'multipart/form-data' in Axios config. A developer follows a generic tutorial and thinks the header must be declared manually.
Incorrect Data Format Passing a standard JavaScript Object {} instead of a FormData instance. Attempting to send a file via { file: myFile } instead of formData.append('file', myFile).
Empty Request Body Sending an empty FormData object or a null reference. The UI allows submission before the FileReader or file input has populated the state.

Method 1: Removing Manual Headers (The Standard Fix)

Section titled “Method 1: Removing Manual Headers (The Standard Fix)”

The most common solution is to let the browser and Axios automatically determine the content type. When Axios detects a FormData object as the request body, it automatically sets the header and generates the correct boundary.

const uploadFile = async (file) => {
const formData = new FormData();
formData.append('file', file);
// THIS CAUSES THE ERROR: The boundary is missing!
const response = await axios.post('/api/upload', formData, {
headers: {
'Content-Type': 'multipart/form-data'
}
});
};
const uploadFile = async (file) => {
const formData = new FormData();
formData.append('file', file);
// DELETE the headers object or the Content-Type key
// Axios will automatically set the boundary for you
const response = await axios.post('/api/upload', formData);
return response.data;
};

Why this works: By omitting the header, the browser’s XMLHttpRequest or Fetch API creates a header that looks like this: Content-Type: multipart/form-data; boundary=----WebKitFormBoundaryABC123. Multer uses that boundary to slice the incoming stream.


Method 2: Verifying Backend Multer Configuration

Section titled “Method 2: Verifying Backend Multer Configuration”

If the frontend is correct, the root cause may lie in how Express is processing the route. Ensure Multer is initialized correctly and applied to the specific route.

const express = require('express');
const multer = require('multer');
const upload = multer({ dest: 'uploads/' });
const app = express();
// Error: Using generic app.use(upload.single()) globally often causes issues
app.use(upload.single('file'));
const express = require('express');
const multer = require('multer');
const upload = multer({ dest: 'uploads/' });
const app = express();
// Apply multer middleware ONLY to the specific upload route
app.post('/api/upload', upload.single('file'), (req, res) => {
if (!req.file) {
return res.status(400).send('No file uploaded.');
}
res.status(200).json({ message: 'File uploaded successfully' });
});

Technical Tip: Ensure the string passed to upload.single('file') matches the key name used in formData.append('file', ...).

  1. Use Axios Interceptors for Debugging: If you have a global Axios instance with default headers, it might be injecting a Content-Type. Use an interceptor to log headers during debugging to ensure nothing is being overwritten.

    axios.interceptors.request.use(config => {
    console.log('Request Headers:', config.headers);
    return config;
    });
  2. Environment Configuration: Ensure your CORS settings on the Express server allow for multipart/form-data. Use the cors package and ensure allowedHeaders includes Content-Type.

  3. Validate FormData on Frontend: Always check if the file exists before appending.

    if (fileInput.current.files[0]) {
    formData.append('file', fileInput.current.files[0]);
    }
  4. Use Postman for Root Cause Isolation: To determine if the issue is in reactjs or Express, test your backend endpoint with Postman using the form-data body type. If Postman works but React fails, the issue is your Axios configuration.

  5. Handling Large Files: For large uploads, configure Multer limits to prevent the server from crashing, which can sometimes manifest as a generic stream error.

    const upload = multer({
    dest: 'uploads/',
    limits: { fileSize: 10 * 1024 * 1024 } // 10MB limit
    });