{"id":17824,"library":"multer2","title":"Multer","description":"Multer is a Node.js middleware specifically designed for handling `multipart/form-data`, primarily used for processing file uploads in web applications built with the Express.js framework. It efficiently parses incoming request bodies and populates `req.body` with text fields and `req.file` or `req.files` with uploaded files, depending on the configured upload strategy. Built on top of `busboy`, Multer focuses exclusively on `multipart/form-data` and will not process other form encodings. The current stable version is 2.1.1, released on March 4, 2026, with a consistent release cadence that includes frequent security patches. It is a widely adopted library within the Express ecosystem for file upload functionalities.","status":"active","version":"1.1.1","language":"javascript","source_language":"en","source_url":"https://github.com/expressjs/multer","tags":["javascript","form","post","multipart","form-data","formdata","express","middleware"],"install":[{"cmd":"npm install multer2","lang":"bash","label":"npm"},{"cmd":"yarn add multer2","lang":"bash","label":"yarn"},{"cmd":"pnpm add multer2","lang":"bash","label":"pnpm"}],"dependencies":[{"reason":"Multer is built on top of `busboy` for efficient parsing of `multipart/form-data` requests.","package":"busboy","optional":false},{"reason":"Multer is designed as an Express.js middleware and is predominantly used within Express applications.","package":"express","optional":true}],"imports":[{"note":"The default export is the main Multer function used to configure and create middleware instances. While `require()` is prevalent in older Express.js examples and CJS environments, ESM `import` is recommended for modern Node.js projects.","wrong":"const multer = require('multer');","symbol":"multer","correct":"import multer from 'multer';"},{"note":"Use the `multer.diskStorage()` factory method to create a storage engine for saving uploaded files to disk. It provides callbacks for customizing destination and filename. Do not attempt to import `DiskStorage` directly as a named export.","wrong":"import { DiskStorage } from 'multer'; const storage = new DiskStorage({...});","symbol":"multer.diskStorage","correct":"import multer from 'multer'; const storage = multer.diskStorage({...});"},{"note":"Use the `multer.memoryStorage()` factory method to store uploaded files in memory as `Buffer` objects. This is suitable for smaller files or temporary processing but should be used with caution for large files to avoid memory exhaustion. Do not attempt to import `MemoryStorage` directly as a named export.","wrong":"import { MemoryStorage } from 'multer'; const storage = new MemoryStorage();","symbol":"multer.memoryStorage","correct":"import multer from 'multer'; const storage = multer.memoryStorage();"}],"quickstart":{"code":"import express from 'express';\nimport multer from 'multer';\nimport path from 'path';\nimport { fileURLToPath } from 'url';\nimport { dirname } from 'path';\nimport fs from 'fs';\n\n// ESM equivalent of __dirname\nconst __filename = fileURLToPath(import.meta.url);\nconst __dirname = dirname(__filename);\n\nconst app = express();\nconst port = 3000;\nconst uploadDir = path.join(__dirname, 'uploads');\n\n// Ensure the uploads directory exists\nif (!fs.existsSync(uploadDir)) {\n  fs.mkdirSync(uploadDir, { recursive: true });\n}\n\n// Configure disk storage\nconst storage = multer.diskStorage({\n  destination: function (req, file, cb) {\n    cb(null, uploadDir);\n  },\n  filename: function (req, file, cb) {\n    cb(null, file.fieldname + '-' + Date.now() + path.extname(file.originalname));\n  }\n});\n\nconst upload = multer({ storage: storage });\n\n// Serve a basic HTML form for upload\napp.get('/', (req, res) => {\n  res.send(`\n    <!DOCTYPE html>\n    <html>\n    <head><title>Multer Upload</title></head>\n    <body>\n      <h2>Upload a Single File</h2>\n      <form action=\"/profile-upload\" method=\"post\" enctype=\"multipart/form-data\">\n        <input type=\"file\" name=\"avatar\" />\n        <button type=\"submit\">Upload Avatar</button>\n      </form>\n      <hr>\n      <h2>Upload Multiple Files (max 5)</h2>\n      <form action=\"/gallery-upload\" method=\"post\" enctype=\"multipart/form-data\">\n        <input type=\"file\" name=\"photos\" multiple />\n        <button type=\"submit\">Upload Gallery</button>\n      </form>\n      <hr>\n      <h2>Text-Only Form</h2>\n      <form action=\"/text-data\" method=\"post\" enctype=\"multipart/form-data\">\n        <input type=\"text\" name=\"username\" placeholder=\"Username\" />\n        <button type=\"submit\">Submit Text</button>\n      </form>\n    </body>\n    </html>\n  `);\n});\n\n// Handle single file upload\napp.post('/profile-upload', upload.single('avatar'), (req, res) => {\n  if (req.file) {\n    console.log('Uploaded avatar:', req.file);\n    res.send(`File uploaded successfully: ${req.file.originalname} saved to ${req.file.path}`);\n  } else {\n    res.status(400).send('No file uploaded.');\n  }\n});\n\n// Handle multiple file upload\napp.post('/gallery-upload', upload.array('photos', 5), (req, res) => {\n  if (req.files && req.files.length > 0) {\n    console.log('Uploaded photos:', req.files);\n    res.send(`${req.files.length} files uploaded successfully.`);\n  } else {\n    res.status(400).send('No files uploaded.');\n  }\n});\n\n// Handle text-only multipart form\napp.post('/text-data', upload.none(), (req, res) => {\n  console.log('Received text data:', req.body);\n  res.send(`Text data received: ${JSON.stringify(req.body)}`);\n});\n\napp.listen(port, () => {\n  console.log(`Server listening at http://localhost:${port}`);\n  console.log(`Uploads will be saved to: ${uploadDir}`);\n});","lang":"javascript","description":"Demonstrates basic file upload handling for single files, multiple files (up to 5), and text-only multipart forms using Multer middleware with Express.js, configuring disk storage with dynamic filenames."},"warnings":[{"fix":"Upgrade Node.js to version 10.16.0 or higher. For Node.js versions below 10.16.0, use Multer v1.x.","message":"Multer v2.0.0 introduced a breaking change by raising the minimum supported Node.js version to 10.16.0. Users on older Node.js runtimes must upgrade their Node.js environment or remain on Multer v1.x.","severity":"breaking","affected_versions":">=2.0.0"},{"fix":"Upgrade to Multer v2.1.1 or higher immediately.","message":"Multer v2.1.1 fixes CVE-2026-3520 (GHSA-5528-5vmv-3xc2), a high-severity Denial of Service (DoS) vulnerability due to uncontrolled recursion. This could cause stack overflow by sending malformed requests.","severity":"security","affected_versions":"<2.1.1"},{"fix":"Upgrade to Multer v2.1.1 or higher (as 2.1.1 is the latest patch and includes all prior fixes).","message":"Multer v2.1.0 fixes CVE-2026-2359 (GHSA-v52c-386h-88mc) and CVE-2026-3304 (GHSA-xf7r-hgr6-v32p), both high-severity Denial of Service (DoS) vulnerabilities. These issues could lead to resource exhaustion via dropped connections during file upload or malformed requests and incomplete cleanup.","severity":"security","affected_versions":"<2.1.0"},{"fix":"Upgrade to Multer v2.1.1 or higher.","message":"Multer v2.0.2 fixes CVE-2025-7338 (GHSA-fjgf-rc76-4x9p), a critical security vulnerability.","severity":"security","affected_versions":"<2.0.2"},{"fix":"Upgrade to Multer v2.1.1 or higher.","message":"Multer v2.0.1 fixes CVE-2025-48997 (GHSA-g5hg-p3ph-g8qg), addressing an important security vulnerability.","severity":"security","affected_versions":"<2.0.1"},{"fix":"Upgrade to Multer v2.1.1 or higher.","message":"Multer v2.0.0 fixes CVE-2025-47935 (GHSA-44fp-w29j-9vj5) and CVE-2025-47944 (GHSA-4pg4-qvpc-4q3h), which are critical security vulnerabilities.","severity":"security","affected_versions":"<2.0.0"},{"fix":"Always ensure your HTML form includes the attribute `enctype=\"multipart/form-data\"` for Multer to correctly process the upload.","message":"Multer explicitly only processes `multipart/form-data` forms. If your HTML form omits `enctype=\"multipart/form-data\"`, Multer will not parse the request body, and `req.body`, `req.file`, or `req.files` will be empty or undefined.","severity":"gotcha","affected_versions":">=0.1.0"}],"env_vars":null,"last_verified":"2026-04-23T00:00:00.000Z","next_check":"2026-07-22T00:00:00.000Z","problems":[{"fix":"Ensure the `name` attribute of your file input in the HTML form exactly matches the string passed to Multer methods like `upload.single()`, `upload.array()`, or the `name` property in `upload.fields()`.","cause":"The field name provided in the HTML form's `<input type=\"file\" name=\"...\">` does not match the field name configured in Multer's middleware (e.g., `upload.single('avatar')` expects `name=\"avatar\"`).","error":"MulterError: Unexpected field"},{"fix":"Verify that your HTML form has `enctype=\"multipart/form-data\"`. Check that the `destination` path for `multer.diskStorage` exists and is writable by the Node.js process. Ensure Multer middleware (e.g., `upload.single()`) is correctly placed before your route handler.","cause":"This typically occurs when the HTML form is missing `enctype=\"multipart/form-data\"`, the `destination` directory for disk storage is not writable or does not exist, or the Multer middleware is not correctly applied to the route.","error":"req.file or req.files is undefined (no file uploaded)"},{"fix":"Ensure the `destination` directory is accessible and not locked. For robust error handling, especially in earlier Multer versions, ensure all streams are properly handled or closed. Upgrading to the latest Multer version (v2.1.1+) includes fixes for error/abort handling that might mitigate some stream-related issues.","cause":"This can happen if the destination directory for file uploads is being accessed or locked by another process, or if the Multer stream is not properly drained/closed in older versions or specific error handling scenarios.","error":"Error: EBUSY: resource busy or locked, open '...' (for disk storage)"},{"fix":"Verify that your client-side code (HTML form or API request) correctly sets `Content-Type: multipart/form-data` and constructs the body according to the multipart specification. If using proxies, ensure they are not interfering with the request body.","cause":"This error typically indicates that the incoming request is not a valid `multipart/form-data` request, often due to incorrect client-side configuration, corrupted data, or a proxy/load balancer modifying the request.","error":"Error: Multipart: Boundary not found"}],"ecosystem":"npm","meta_description":null,"install_score":null,"install_tag":null,"quickstart_score":null,"quickstart_tag":null}