Helping you solve those tough coding problems!

Can't set headers after they are sent Can't set headers after they are sent

Published on Mar 23, 2019 by Jamie Munro

When you are using Node.js with Express and you've received the dreaded "Can't set headers after they are sent" where do you even begin. This article will explore common causes of this error, such as calling res.writeHead, res.write, or res.redirect.




For all examples I will start with a generic Express function that looks as follows:


router.get('/',function (req,res,next){
     
});


This function will respond to the homepage of your website. Let's now go through the common scenarios causing Node.js and Express to throw Can't set headers after they are sent.

Calling res.writeHead to early



If in your Express route function, you can call res.setHeader as many times as you like. The second you call res.writeHead or res.write Express has permanently set the headers for the response of your call.

Any further calls to res.setHeader will error with Can't render headers after they are sent to the client.

Here is an example of what to look for:


router.get('/',function (req,res,next){
	 
	 // Call to some middleware
	 // middleware code calls: res.writeHead();
	 
	 res.setHeader('Content-Type', 'text/html');
	 
	 // Exception thrown after setHeader call
});


If you have middleware or your own code that is writing the headers are the response, you will want to set your own headers before calling the offending code:


router.get('/',function (req,res,next){
	 
	 res.setHeader('Content-Type', 'text/html');
	 
	 // Call to some middleware
	 // middleware code calls: res.writeHead();
	 
	 
	 // Finish executing the request
});


Calling res.redirect then setting more data



After you call res.redirect Express has finalized the request. Any further setting of data prior to Express performing the redirect will also cause Can't render headers after they are sent.

Let's look at example that may cause this:


router.post('/',function (req,res,next){
	 
	 // Do something with the post data
	 
	 // Redirect to thank you page
	 res.redirect('/thankyou');
	 
	 // Additional function call that causes error
	 next();
});


In this example, a post request is made. The code does something with it then redirects the user to a thank you page. After this action a call to - in this example - next(); is made that causes the header error.

After calling res.redirect(); be sure no other code is executed:


router.post('/',function (req,res,next){
	 
	 // Do something with the post data
	 
	 // Redirect to thank you page
	 res.redirect('/thankyou');
});


Calling next after response has been returned



The final common scenario that I know about is calling next after res.end has been called. This is once again common when middleware unbeknownst to you calls res.end.


router.get('/',function (req,res,next){
	 
	 // Some middelware that executes
	 // res.end
	 
	 // Additional function call that causes error
	 next();
});


To solve this, ensure the call to next happens before the call to res.end.

Ideally the middleware either doesn't call res.end and your code will be responsible for ending the request OR the middleware calls next for you before it calls res.end.

Hopefully one of these three tips will help you solve the dreaded Can't render headers after they are sent.

Tags: Node.js | node | express

My Books
ASP.NET MVC 5 With Bootstrap and Knockout.js
Knockout.js Building Dynamic Client-Side Applications
20 Recipes for Programming MVC 3
20 Recipes for Programming PhoneGap
Rapid Application Development with CakePHP

Related Posts