All notable changes to this project will be documented in this file. This project adheres to Semantic Versioning.
- Fix CVE-2026-113872 (GHSA-q7qp-rjg7-q26m)
- Accept a field value of exactly
limits.fieldSizebytes, soLIMIT_FIELD_VALUEfires only when the limit is exceeded. This also covers the defaultfieldSizeof 1MB, so a 1048576 byte value is no longer rejected when you set no limits. If you setfieldSizeone higher to work around this, you can drop the extra one (#1481) - Do not add a file to the abort cleanup list when its storage engine reports an error after a
LIMIT_FILE_SIZEabort;DiskStorageno longer tries to unlink an undefined path (#1489)
- Fix CVE-2026-88932 (GHSA-3pph-fpjx-jg34)
- Add
filenametoLIMIT_FILE_SIZEandLIMIT_UNEXPECTED_FILEerrors (#1416) - Accept a function for
limits, called with the request, to set limits per request (#1133) - Add opt-in
flushoption toDiskStorageto fsync files before the callback runs (#1458) - Expose busboy's
defCharset,highWaterMarkandfileHwmoptions (#1465) - Add
streamHandleroption to feed busboy from pre-consumed bodies (Google Cloud Functions, Firebase) (#1466) - Allow
multer.diskStorage()to be called without options (#1471) - Decode WHATWG-escaped characters (
%0A,%0D,%22) in field names, matchingfile.originalnamesince 2.3.0:req.bodykeys,file.fieldnameanderr.fieldnow carry the real name. If you matched the escaped spelling as a workaround, use the real name now (#1473) - Report the decoded filename in
err.filenameonLIMIT_FILE_SIZEerrors, matchingfile.originalname(#1478) - Reject non-integer or negative
limitsvalues at construction time; a float limit silently disabled the check (#1395, #1335) - Accept requests with exactly
limits.partsparts;LIMIT_PART_COUNTnow fires only when the limit is exceeded. If you setpartsone higher to work around this, you can drop the extra one (#1446) - Files skipped by
fileFilterno longer count towardsmaxCount(#1426) - Change the
LIMIT_UNEXPECTED_FILEmessage to "Unexpected file field" (#426) - Remove the
concat-streamdependency (#1356) - Docs: add JSDoc to the public API and document the storage engine stream contract (#1467, #1468)
- Docs: add FormData upload examples (#896)
- Docs: remove the translated READMEs (#1463)
- Internal: run the test suite on macOS (#1464)
- Fix CVE-2026-77078 (GHSA-wc9g-mqfw-jrwm)
- Fix CVE-2026-77037 (GHSA-qfvm-cv95-jqjf)
- Fix CVE-2026-77063 (GHSA-qvfw-j98x-7q72)
- Fix CVE-2026-82333 (GHSA-535w-7cp7-47q4)
- Add
MulterErrorcodesINVALID_FIELD_NAMEandSTREAM_DESTROYED - Add opt-in
limits.fieldArrayIndexLimitto bound numeric array indexes in field names (#1438) - Accept files whose size is exactly
limits.fileSize(#1407) - Preserve the caller's async context (
AsyncLocalStorage) when callingnext()(#1124) - Decode WHATWG-escaped characters (
%0A,%0D,%22) infile.originalname(#1421) - Do not crash when
fileFilterinvokes its callback more than once (#1427) - Use a fallback message for
MulterErrorcodes without a mapping (#1448) - Docs: clarify
preservePathandparts, usecrypto.randomBytesin theDiskStorageexample (#1414, #1430, #1436) - Docs: add Indonesian, Japanese and Tamil translations and refresh all translations from the current README (#1431, #1354, #1462)
- Internal: run the test suite on Windows (#1334)
- Fix CVE-2026-3520 (GHSA-5528-5vmv-3xc2)
- fix error/abort handling
- Add
defParamCharsetoption for UTF-8 filename support (#1210) - Fix CVE-2026-2359 (GHSA-v52c-386h-88mc)
- Fix CVE-2026-3304 (GHSA-xf7r-hgr6-v32p)
- Breaking change: The minimum supported Node version is now 10.16.0
- Fix CVE-2025-47935 (GHSA-44fp-w29j-9vj5)
- Fix CVE-2025-47944 (GHSA-4pg4-qvpc-4q3h)
- Fix out-of-band error event from busboy (#1177)
- No changes
- Bugfix: Bump busboy to fix CVE-2022-24434 (#1097)
- Breaking: Require Node.js 10.16.0 or later (#1097)
- Bugfix: Handle missing field names (#913)
- Docs: Add Vietnamese translation (#803)
- Docs: Improve Spanish translation (#948)
- Bugfix: Avoid deprecated pseudoRandomBytes function (#774)
- Docs: Add Português Brazil translation for README (#758)
- Docs: Clarify the callback calling convention (#775)
- Docs: Add example on how to link to html multipart form (#580)
- Docs: Add Spanish translation for README (#838)
- Docs: Add Math.random() to storage filename example (#841)
- Docs: Fix mistakes in russian doc (#869)
- Docs: Improve Português Brazil translation (#877)
- Docs: Update var to const in all Readmes (#1024)
- Internal: Bump mkdirp version (#862)
- Internal: Bump Standard version (#878)
- Docs: Add Russian translation for README (#662)
- Docs: Patch zh-CN README base on newest README (#670)
- Docs: Fix broken link in Readme (#679)
- Docs: Fix broken link in Chinese Readme (#730)
- Docs: Fix typo in Russian README (#738)
- Docs: Add unit for fieldSize in busboy limit params (#734)
- Internal: Make unit tests compatible with Node.js 13.x (#752)
- Bugfix: Make sure that req.file.buffer always is a Buffer
- Feature: Make Multer errors inherit from MulterError
- Bugfix: Bump vulnerable dependency
- Feature: Expose preservePath option
- Bugfix: Prevent Multiple Errors from Crashing
- Feature: add .none() for accepting only fields
- Feature: accept any file, regardless of fieldname
- Bugfix: always report limit errors
- Bugfix: drain the stream before considering request done
- Bugfix: propagate all errors from busboy
- Bugfix: ensure file order is correct
- Bugfix: don't hang when hitting size limit
- Bugfix: decrement pending writes on error
- Introduce storage engines
- Specify expected fields
- Follow the W3C JSON form spec