multer: Unexpected end of form at Multipart._final

Getting this error while using multer with react.js and node.js

Unexpected end of form
at Multipart._final (E:\nearme\backend\node_modules\busboy\lib\types\multipart.js:588:17)
at callFinal (internal/streams/writable.js:610:10)
at processTicksAndRejections (internal/process/task_queues.js:80:21) {
storageErrors: []
}

react.js file

const fd = new FormData();
fd.append("profile", data.profile);
fd.append("name", data.name);
fd.append("email", data.email);
fd.append("password", data.password);

const res = await axios.post("http://localhost:8000/signup/data", fd, {
  headers: { "Content-Type": "multipart/form-data" },
});

node js file:

const multer = require("multer");
const storage = multer.diskStorage({
destination: function (req, file, cb) {
cb(null, "../public");
},
filename: function (req, file, cb) {
const uniqueSuffix = Date.now() + "-" + Math.round(Math.random() * 1e9);
cb(null, file.fieldname + "-" + uniqueSuffix);
},
});

const upd = multer({ storage: storage }).single("profile");
router.post("/data", (req, res) => {
upd(req, res, function (err) {
if (err instanceof multer.MulterError) {
console.log("A Multer error occurred when uploading");
} else if (err) {
console.log("An unknown error occurred when uploading", err);
}
});
});

For more details about project refer this https://github.com/amulagrawal02/nearme

About this issue

  • Original URL
  • State: open
  • Created 2 years ago
  • Reactions: 33
  • Comments: 36 (2 by maintainers)

Commits related to this issue

Most upvoted comments

I have the same issue 😦

We had a similar issue on 1.4.5-lts.1 and 1.4.4-lts.1. Downgrading to 1.4.3 fixed the issue for us. NOTE: 1.4.3 has an outstanding security issue due to dicer.

For people still experiencing this issue, I found a similar bug when using multer or busboy in a Google Cloud Function with an express router.

I found an answer that fixed the issue for me here: https://github.com/mscdex/busboy/issues/296#issuecomment-1107458297

A lot of those “cloud function” services will buffer the contents of the request somewhere, so normal node.js http request stream data isn’t available and is most likely what is causing the error. If that’s the case you’ll need to find out where the data is being stored and then bb.end(data) instead of req.pipe(bb).

I believe multer is using req.pipe in the middleware, which may be causing the issue. I am still trying to make multer work with our Cloud Function with no luck. So I am using busboy with bb.end(req.rawBody) instead.

Hope this helps!

public uploadController = async (req: Request, res: Response, next: NextFunction) => {
  const bb = busboy({ headers: req.headers });
  
  bb.on('file', (name, file, info) => {
    const { filename, encoding, mimeType } = info;
    console.log(
      `File [${name}]: filename: %j, encoding: %j, mimeType: %j`,
      filename,
      encoding,
      mimeType
    );
    file.on('data', (data) => {
      console.log(`File [${name}] got ${data?.length} bytes`);
    }).on('close', () => {
      console.log(`File [${name}] done`);
    });
  });
  bb.on('field', (name, val, info) => {
    console.log(`Field [${name}]: value: %j`, val);
  });
  bb.on('close', () => {
    console.log('Done parsing form!');
    res.status(200).send({ message: 'Done parsing form!' });
  });
  
  bb.end(req.body);
};

I have the same issue

My problem was this line:

   app.use(
    bodyParser.urlencoded({
      extended: false,
    })
  );

replaced it by

   app.use(
    bodyParser.urlencoded({
      extended: true,
    })
  );

and it worked.

i also have the same issue and nothing here seems to work

I’m having the same issue, there should be a more convenient way than downgrading (I’m on 1.4.5-lts.1), in my case I do have body-parser as it’s needed on other routes so that might collide with multer? I tried setting bodyparser.urlencoded({extended:true}) before the multer middleware as mentioned here but that didn’t solve it for me, it’s strange because I can’t reproduce this locally, this only happens on our live environments. Kindly asking for help on this one, here is the full issue: https://stackoverflow.com/questions/76064309/unexpected-end-of-form-at-callfinal-error

We had a similar issue on 1.4.5-lts.1 and 1.4.4-lts.1. Downgrading to 1.4.3 fixed the issue for us. NOTE: 1.4.3 has an outstanding security issue due to dicer.

Can confirm, that it works with a downgrade to 1.4.3 … Btw: with the current version of busboy 1.6.0 the same error occurs.

if you’re reading this because you get an uncaughtException “Unexpected end of form” the root cause is that the multer code removes the busboy error listener too early, the fix is in https://github.com/expressjs/multer/pull/1177. It would be great the Multer team merges it as it is trivial to repro the issue.

For NextJS, you just have to add this code at the top of the file.

export const config = { api: { bodyParser: false } };

Can confirm, that it works with a downgrade to 1.4.3 … Btw: with the current version of busboy 1.6.0 the same error occurs.

Yes! downgrading to multer 1.4.3 worked! thanks

Is there any plan to fix this? It’s just quite ugly having to use busboy for this compare to a nice decorator

I just make another method to upload files that are not related to Multer instead you can use existing packages to do that

//handler.js using next-connect

import multiparty from "multiparty";
import bodyParser from "body-parser";
import handler from "./handler";
import { promises as fs } from "fs";

handler.use(async (req, res, next) => {
  const filePath = path.join(process.cwd(), 'public', 'uploads');
  console.log(filePath);
  const form = new multiparty.Form({ uploadDir: filePath, });

  await form.parse(req, function (err, fields, files) {
    req.body = fields;
    req.files = files;
    next();
  });
});

// Define the route handler
handler.post(async (req, res) => {
  // console.log(req.body, req.files);
  res.json(req.files);
  // res.json(fields, files);
});
//frontend request demo 
async function submitForm(e) {
    e.preventDefault();
    const company_slug = slugify(coName.toLowerCase());
    // console.log(img, coName, company_slug, description, option);

    const formData = new FormData();
    formData.append("name", coName);
    formData.append("description", description);
    formData.append("image", ufile);
    formData.append("company_slug", company_slug);
    formData.append("option", option);
    formData.append("_csrf",  props?.props?.data,);

    try {
      const result = await axios.post(
        `/api/create`,
        formData,
        {
          withCredentials: true,
          headers: {
            Accept: "application/json",
            "Content-Type":"multipart/form-data",
            "xsrf-token": props?.props?.csrf,
          },
        }
      );

      console.log(result.data);
    } catch (error) {
      console.log(error);
    }
  }

This is a demo that you can run and get the result also after upload you can check the file if it was ok and then rename otherwise delete this or something else here in their full doc of https://www.npmjs.com/package/multiparty

Note: Ignore another thing that I use in my frontend request demo just see how I send the request 😃

Kindly solve this issue the only solution i found is downgrading to version @1.4.2, but this version contains a severe levels of security issues.

Yes! downgrading to multer 1.4.3 worked! thanks great