req.file returns undefined when using multer middleware for file uploads

I’m having trouble with file uploads using multer. When I try to access req.file in my route handler, it shows up as undefined and I get an error when trying to read its properties.

I followed a tutorial but something isn’t working right. Here’s what I have set up:

const multer = require('multer');

const diskStorage = multer.diskStorage({
  destination: function(req, file, callback) {
    callback(null, './uploads/avatars');
  },
  filename: function(req, file, callback) {
    callback(null, Date.now() + '-' + file.originalname);
  }
});

const filterFiles = (req, file, callback) => {
  if (file.mimetype === 'image/jpeg' || file.mimetype === 'image/png') {
    callback(null, true);
  } else {
    callback(null, false);
  }
};

const fileUpload = multer({
  storage: diskStorage,
  limits: {
    fileSize: 5 * 1024 * 1024
  },
  fileFilter: filterFiles
});

My database model:

const avatarSchema = new mongoose.Schema({
    avatarPath: String
})

const Avatar = mongoose.model('Avatar', avatarSchema)

The route that handles uploads:

app.post('/upload-avatar', fileUpload.single('avatar'), function(req, res){
    console.log(req.file); // this prints undefined
    const newAvatar = new Avatar({
        avatarPath: req.file.path // error happens here
    })
    newAvatar.save()
})

HTML form:

<form action="/upload-avatar" method="POST" enctype="multipart/form-data">
    <input type="file" name="avatar" />
    <button type="submit">Submit</button>
</form>

When I check req.file it’s always undefined. What could be causing multer to not process the uploaded file?

Had this exact issue last month - drove me crazy for hours. Your code looks right, but here’s what caught me: when multer’s fileFilter rejects a file, req.file becomes undefined but the request still goes through. You’re only allowing jpeg and png, so double-check you’re actually uploading those formats. I was testing with webp images and couldn’t figure out why everything was undefined. Also, make sure your file size is under that 5MB limit. What helped me debug: temporarily remove the fileFilter and limits to see if req.file appears, then add restrictions back one by one. Your error handling should also check if req.file exists before accessing its properties.

Check your form submission method. Had the same problem - turns out my form wasn’t sending the file data at all. Add some debug logging in your route before hitting req.file and log req.headers to make sure content-type shows multipart/form-data. Double-check your form’s name attribute matches what you put in fileUpload.single(‘avatar’). Browser caching got me too - try incognito or clear your cache. If the folder’s there and form looks right, something’s wrong with how the request hits your server.

first, make sure the uploads/avatars folder is present. multer doesn’t make dirs on its own, so it might fail if missing. also, log req.body to see if any data comes through.