DEV Community

Cover image for Fix "Unexpected field" Error From Multer
Maxim Orlov
Maxim Orlov

Posted on • Edited on • Originally published at maximorlov.com

Fix "Unexpected field" Error From Multer

This article was originally published a day earlier at https://maximorlov.com/fix-unexpected-field-error-multer/

You set out to implement file uploads in Node.js, only to get blocked by this particular error:

MulterError: Unexpected field

What does this cryptic message even mean?!

By now you've already spent several hours trying to solve this problem. Why does implementing a simple file upload feature have to be so hard?!

It doesn't have to be this way though. Writing an endpoint that accepts, parses and uploads a file in Node.js can be straightforward.

After reading this article, you'll turn an annoying error into something you'll solve in less than 5 minutes!

Read on or if you prefer video, watch it below.

Input name needs to match multer function argument

The foremost cause for this error is when the name attribute of the file input doesn't match the argument passed to one of multer's middleware functions.

Two code snippets: one shows an HTML form with one file input, another shows an Express POST route with a multer middleware to parse the multipart/form-data request. Both are linked with an arrow pointing at the input name in HTML, and multer argument on the server indicating they should be the same

The NAME you use in multer's upload.single(NAME) middleware function (or any of the other functions discussed below) must be the same as the name attribute of the input element <input type="file" name="NAME" />.

Therefore, you have to double-check that these values are an exact match. Pay extra attention to invisible whitespace or characters that may look the same but have a different Unicode value. It's better to copy-paste the value from one place to another.

Multer is strict in what input it accepts from the client, and for a good reason. File uploads can be a big vulnerability for backend servers. It's easy for a bad actor to overflow the server with a huge amount of files, or send malformed data that breaks the parser and potentially gives the hacker access to the server. Multer is designed with a mindset to trust nothing that comes from the client so it can protect your server from a potential DoS attack.

Depending on the form data you're expecting from the client, multer provides you with different middleware functions:

  • no file (text only) - upload.none()
  • single file - upload.single(fieldname)
  • multiple files, single input - upload.array(fieldname[, maxCount])
  • multiples files, multiple inputs - upload.fields(fields) where fields is an array of objects with name and optionally maxCount keys
  • any of the above - upload.any() (avoid if possible)

multer.any() is oftentimes used as a quick fix. This is dangerous and can make your server vulnerable to attacks. multer.any() will accept all files sent by the client which can lead to unexpected values further down in your application logic. Especially when used as a global middleware instead of a route-specific middleware.

It's always better to fix the error by making sure field names are the same, instead of using multer.any().

If you decide to use multer.any(), use it only on specific routes and make sure you're handling all uploaded files.

Use the appropriate middleware function so that the form data received from the client is allowed to pass through. When you see an "Unexpected field" error from Multer, it's because the middleware function is rejecting some (or all) form data.

With FormData

When you're using FormData to programatically construct a form, input name is the first argument to the .append() function:

// Constructing a form in JavaScript
// Input name is the first argument of `append` function
const formData = new FormData();
formData.append('NAME', file);
Enter fullscreen mode Exit fullscreen mode

You then have to make sure that the same value, NAME in this case, is used as the fieldname argument in the middleware function:

// Pass the same input name to the multer middleware function
app.post('/upload', upload.single('NAME'), (req, res) => {
    // ...
});
Enter fullscreen mode Exit fullscreen mode

Inputs with multiple files might have a name ending with []

In some cases, you might have a client that appends [] to the input name if it has multiple files.

When you configure multer to accept a photos field but the client sends photos[] instead, multer will throw a MulterError: Unexpected field error.

To fix the error, append [] to the fieldname argument in the middleware function: upload.array('photos[]').

Finding the unexpected field

Error messages from multer are rather cryptic. They don't give you much information to help you find the root cause of the problem.

There's a way to extract a little bit more information from the error thrown by multer and find the rejected field.

Add an error handling middleware and log the error argument. More specifically, the field property of the error tells you which input name multer has an issue with:

// Logging the rejected field from multer error
app.use((error, req, res, next) => {
  console.log('This is the rejected field ->', error.field);
});
Enter fullscreen mode Exit fullscreen mode

In a Node.js production application, you'd want to replace console.log with a proper logging mechanism to avoid messy logs and quickly find what you're looking for.

Having found the rejected field, you're a step closer to solving the error since you know where to start looking.

Other possible causes

If the error persists after verifying the input name matches the multer function argument, there might be something else going on. Here are three other possible causes for this error, and a solution for each.

Conflicting multer instances

I've seen this come up a few times so it's worth mentioning.

Make sure there is only one multer instance used in the middleware chain of any particular route.

What do I mean by this? Let's look at an example:

// Typical Express application
const express = require('express');
const app = express();

app.use(upload.array());

// Some more express middleware ...

app.post('/upload', upload.single('photo'), (req, res) => {
  // ...
});
Enter fullscreen mode Exit fullscreen mode

Can you see what's wrong with the above example?

There's a multer instance used on all routes (upload.array()) and another multer instance (upload.single('photo')) specific to the /upload route.

If you try to upload a single file with the correct input name (photo), the first multer instance will throw an error and the code never reaches the second multer instance. That's because upload.array() is missing a fieldname argument and it will always throw an error on file uploads.

If you're using multer at top of your middleware chain to get access to the authentication token in the body, you should move it to the request headers instead. It's standard practice to put an authentication token in the Authorization header.

Unaccounted file inputs

Remember when I said earlier that multer is strict about accepting form data from the client?

Even if you made sure the field names are the same, you will still face this error if there are file inputs you haven't told multer about.

You can configure multer to accept multiple fields with the upload.fields(fields) method. fields is an array of objects with a name, and optionally maxCount, key.

For example, the following HTML form has two file inputs:

<!-- Form with two file inputs: "avatar" and "photos" -->
<form action="/upload" method="POST" enctype="multipart/form-data">
  <input type="file" name="avatar" />
  <input type="file" name="photos" multiple />
  <input type="submit" value="Send" />
</form>
Enter fullscreen mode Exit fullscreen mode

To configure multer to accept the above form, you would have to write the following code:

// Configure multer to accept two file inputs: "avatar" and "photos".
// The "avatar" and "photos" inputs are allowed to have up to 1 and 6 files, respectively.
app.post(
  '/upload',
  upload.fields([
    { name: 'avatar', maxCount: 1 },
    { name: 'photos', maxCount: 6 },
  ]),
  (req, res) => {},
);
Enter fullscreen mode Exit fullscreen mode

This configuration tells multer we're expecting two file input fields named "avatar" and "photos" with no more than 1 and 6 files, respectively. In case there are other fields present, multer will throw an "Unexpected field" error.

Number of files exceeding the configured limit

When you see a MulterError: Unexpected field error, you don't suspect the reason to be the number of files exceeding the configured limit.

If you're using a middleware function that allows multiple files to be uploaded (.array() or .fields()), make sure the number of files uploaded doesn't exceed the maxCount value.

To quickly check if this might be the cause, set maxCount to a huge number (eg.: upload.array('photos', 9999)). If the error disappears, you've found the issue. Either increase maxCount to allow more files to be uploaded at once, or change the client to send fewer files at a time.

Conclusion

Fixing cryptic multer errors and getting file uploads to work properly in Node.js can be a frustrating experience.

The foremost reason for the "Unexpected field" error is when the file input name doesn't match the argument passed to the multer function.

Other possible reasons for this error are conflicting multer instances, unaccounted file inputs and exceeding the number of files limit.

Having a hard time implementing file uploads in Node.js? Become an expert at handling file uploads with this FREE reference guide. Code examples, concise explanations and best practices are waiting for you.

Top comments (0)