Home:ALL Converter>ERR_HTTP_HEADERS_SENT: Cannot set headers after they are sent to the client

ERR_HTTP_HEADERS_SENT: Cannot set headers after they are sent to the client

Ask Time:2018-09-01T04:32:23         Author:lourdesr

Json Formatter

I'm facing this weird issue in NodeJS when using with Passport.js, Express and Mongoose. Basically, I get an error saying "Cannot set headers after they are sent to the client" even though I don't send more than one header.

I've read other posts and tried them out as well, and none of them worked.

I've dug through github issues and I can't seem to find a solution. I get the problem that this error is triggered when I send multiple response headers, but the fact is that I am not sending multiple headers. It seems just weird.

This is my stack trace:

(node:9236) DeprecationWarning: current URL string parser is deprecated, and will be removed in a future version. To use the new parser, pass option { useNewUrlParser: true } to MongoClient.connect.

Server Running on port 5000
MongoDB Connected Error
[ERR_HTTP_HEADERS_SENT]: Cannot set headers after they are sent to the client
  at validateHeader (_http_outgoing.js:503:11)
   at ServerResponse.setHeader (_http_outgoing.js:510:3)
   at ServerResponse.header (/Users/lourdesroashan/code/github/devlog/node_modules/express/lib/response.js:767:10)
   at ServerResponse.json (/Users/lourdesroashan/code/github/devlog/node_modules/express/lib/response.js:264:10)
   at Profile.findOne.then.profile (/Users/lourdesroashan/code/github/devlog/routes/api/profile.js:27:30)
   at <anonymous>

This is my server code:

router.get("/userprofile", passport.authenticate('jwt', { session: false }), (req, res) => {

  Profile.findOne({ user: req.user.id }).then(profile => {
    if (!profile) {
      return res.status(404).json({ error: "No Profile Found" });
    }
    else {
      res.json(profile);
    }
  }).catch(err => {
    console.log(err);
  })
});

I understand what the error means, but from what I know, I don't think I am sending multiple headers, I even checked by console.log that only one of the blocks is run.

Thank you so much in advance! :)

Full Code at: https://github.com/lourdesr/devlog

EDIT:

I figured it out. It was a problem in my passport.js while trying to get the authenticated user. I forgot to use 'return' on the 'done' method, which had caused it. Just added the return statement and it worked!

Author:lourdesr,eproduced under the CC 4.0 BY-SA copyright license with a link to the original source and this disclaimer.
Link to original article:https://stackoverflow.com/questions/52122272/err-http-headers-sent-cannot-set-headers-after-they-are-sent-to-the-client
Eugène Beliaev :

There is a simple fix for the node error [ERR_HTTP_HEADERS_SET]. You need to add a return statement in front of your responses to make sure your router exits correctly on error:\nrouter.post("/", async (req, res) => {\n \n let user = await User.findOne({email: req.body.email}); \n if (!user) **return** res.status(400).send("Wrong user");\n \n});\n",
2020-12-15T22:17:21
Bilal Amin :

In react, if your are calling the function in useEffect hook, make sure to add a dependency to the dependency Array.",
2022-02-02T08:37:51
Saeed Awan :

Because of multiple response sending in your request. if you use return key word in your else condition your code will run properly\nif (!profile) {\n return res.status(404).json({ error: "No Profile Found" });\n}\nelse {\n **return** res.json(profile);\n}\n",
2020-12-14T07:11:54
Rajesh Khadka :

This also happen when you tries to send the multiple response for a same request !!\nSo make sure you always use return keyword to send response to client inorder to stop the further processing !!",
2022-04-14T17:53:14
Yash Jadhav :

Where you have this:\nif (!user) { errors.email = "User not found"; res.status(404).json({ errors }); }\nYou need to change it to:\nif (!user) { errors.email = "User not found"; return res.status(404).json({ errors }); }",
2022-07-04T12:20:13
user8758751 :

I got the same error using express and mongoose with HBS template engine. I went to Expressjs and read the docs for res.render, and it says // if a callback is specified, the rendered HTML string has to be sent explicitly. So I wasnt originally sending my html explicitly in the callback,. This is only for a contact form btw, not login info, albeit GET\n\n//Original\nlet { username, email } = req.query; //My get query data easier to read\n\nres.status(200).render('index', { username, email });\n\n\n\n//Solution without error. Second param sending data to views, Third param callback\n\nres.status(200).render('index', { username, email }, (err, html)=>{\n res.send(html);\n });\n",
2019-08-14T20:10:05
KingJoeffrey :

I had this error from an if statement not having an else block.\nif(someCondition) {\nawait () => { } \n\n}\n\nawait () => { } \n\n\nI changed the above to this below and solved my issue\nif(someCondition) {\nawait () => { } \n\n} else { \nawait () => { } \n}\n\n\n",
2022-04-09T20:19:22
jfriend00 :

That particular error occurs whenever you try to send more than one response to the same request and is usually caused by improper asynchronous code.\n\nThe code you show in your question does not appear like it would cause that error, but I do see code in a different route here that would cause that error.\n\nWhere you have this:\n\nif (!user) {\n errors.email = \"User not found\";\n res.status(404).json({ errors });\n}\n\n\nYou need to change it to:\n\nif (!user) {\n errors.email = \"User not found\";\n res.status(404).json({ errors });\n // stop further execution in this callback\n return;\n}\n\n\nYou don't want the code to continue after you've done res.status(404).json({ errors }); because it will then try to send another response.\n\n\n\nIn addition, everywhere you have this:\n\nif (err) throw err;\n\n\ninside an async callback, you need to replace that with something that actually sends an error response such as:\n\nif (err) {\n console.log(err);\n res.sendStatus(500);\n return;\n}\n\n\nthrowing inside an async callback just goes back into the node.js event system and isn't thrown to anywhere that you can actually catch it. Further, it doesn't send a response to the http request. In otherwords, it doesn't really do what the server is supposed to do. So, do yourself a favor and never write that code in your server. When you get an error, send an error response.\n\n\n\nSince it looks like you may be new here, I wanted to compliment you on including a link to your full source code at https://github.com/lourdesr/devlog because it's only by looking at that that I was able to see this place where the error is occuring.",
2018-08-31T20:59:23
Page COW :

For me, I accidentally put a res.status inside of a for loop. So my server would trigger the error the second time a res.status was returned. I needed to put the res.status outside of the for loop so it would only trigger once within the function.",
2022-08-30T18:59:39
Chunky Chunk :

I was receiving this error because of a foolish mistake on my part. I need to be more careful when referencing my other working code. The truly embarrassing part is how long I spent trying to figure out the cause of the error. Ouf! \n\nBad:\n\nreturn res\n .send(C.Status.OK)\n .json({ item });\n\n\nGood:\n\nreturn res\n .status(C.Status.OK)\n .json({ item });\n",
2019-08-05T09:31:59
Reda El Ouahabi :

\nFirst of all : make sure you didn't miss any asynchronous action without an async/await or use promises/callbacks.\nThen attach any res with the return keyword : return res.status(..).json({});\nAnd finally which was my problem: don't use return res.sendStatus if you always have some return res... inside a callback function, but you can always do a retun res.status(); \nin my case it was : \nusers.save((err,savedDoc){ \nif(err) return res.status(501).json({}) \nres.status(200).json({}); \n}); \nreturn res.status(500); // instead ofdoing return res.sendStatus(500)\n",
2022-12-07T02:35:29
Mohammad Reza Mrg :

Use ctrl + F hotkey and find all 'res.' keywords\nthen replace them with 'return res.',\nchange all 'res.' to 'return res.'\n\nsomething like this:\nres.send() change to --> return res.send()\nmaybe you have 'res.' in some block, like if() statement",
2021-05-06T13:06:27
sina :

you have to enable Promises in your programm, in my case i enabled it in my mongoose schema by using mongoose.Promise = global.Promise .\nThis enables using native js promises.\n\nother alternatives to this soloution is :\n\nvar mongoose = require('mongoose');\n// set Promise provider to bluebird\nmongoose.Promise = require('bluebird');\n\n\nand\n\n// q\nmongoose.Promise = require('q').Promise;\n\n\nbut you need to install these packages first.",
2020-02-11T16:19:05
Ivan of uganda :

Sorry for the Late response, \nAs per the mongoose documentation \"Mongoose queries are not promises. They have a .then() function for co and async/await as a convenience. However, unlike promises, calling a query's .then() can execute the query multiple time\"\n\nso to use promises\n\nmongoose.Promise = global.Promise //To use the native js promises\n\n\nThen\n\nvar promise = Profile.findOne({ user: req.user.id }).exec()\npromise.then(function (profile){\n if (!profile) {\n throw new Error(\"User profile not found\") //reject promise with error\n }\n return res.status(200).json(profile) //return user profile \n}).catch(function (err){\n console.log(err); //User profile not found\n return res.status(404).json({ err.message }) //return your error msg\n})\n\n\nhere is an nice article about switching out callbacks with promises in Mongoose\n\nand this answer on mongooses promise rejection handling Mongoose right promise rejection handling",
2019-05-09T10:10:08
Christhopher Lion :

My problem besides not returning, i was forgetting to await an asynchronous function in the handler. So handler was returning and after a bit the async function did its thing. 🤦🏻‍♀️\nBefore:\nreq.session.set('x', {...});\nreq.session.save();\nreturn req.status(200).end();\n\nWhen i needed to await:\nreq.session.set('x', {...});\nawait req.session.save();\nreturn req.status(200).end();\n",
2021-10-13T11:42:26
yy