Rectangle 27 0

javascript Error: Can't set headers after they are sent to the client?


This happens when response was delivered to client and again you are trying to give response. You have to check in your code that somewhere you are returning response to client again which causes this error. Check and return response once when you want to return.

Note
Rectangle 27 0

javascript Error: Can't set headers after they are sent to the client?


function(req, res, next)
http.ServerResponse
next()
res
res.addTrailers(headers)
res.attachment(filename)
res.charset = 'utf-8'
res.clearCookie(name[, options])
res.contentType(type)
res.cookie(name, val[, options])
res.end([data], [encoding])
res.end(data)
res.getHeader(name)
res.header(key[, val])
res.json(obj[, headers|status[, status]])
res.partial(view[, options])
res.redirect(url[, status])
res.removeHeader(name)
res.render(view[, options[, fn]])
res.send(body|status[, headers|status[, status]])
res.sendfile(path[, options[, callback]])
res.setHeader(name, value)
res.statusCode = 404
res.write(chunk, encoding='utf8')
res.write(data)
res.writeContinue()
res.writeHead(statusCode)
res.writeHead(statusCode, [reasonPhrase], [headers])
return
return next([err])
writeHead

In your case, you called res.redirect(), which caused the response to become Finished. Then your code threw an error (res.req is null). and since the error happened within your actual function(req, res, next) (not within a callback), Connect was able to catch it and then tried to send a 500 error page. But since the headers were already sent, Node.js's setHeader threw the error that you saw.

Response can be in either Head/Body and remains in its current state:

Response must be in Head and becomes Finished:

Response must be in Head and remains in Head:

The error "Error: Can't set headers after they are sent." means that you're already in the Body or Finished state, but some function tried to set a header or statusCode. When you see this error, try to look for anything that tries to send a header after some of the body has already been written. For example, look for callbacks that are accidentally called twice, or any error that happens after the body is sent.

also watch out for this classic mistake: res.redirect() doesn't stop statement execution... so return after it. Otherwise other code could be executed which could unintentiallly cause the famous header error. Thanx for the explanation!

Note
Rectangle 27 0

javascript Error: Can't set headers after they are sent to the client?


For anyone that's coming to this and none of the other solutions helped, in my case this manifested on a route that handled image uploading but didn't handle timeouts, and thus if the upload took too long and timed out, when the callback was fired after the timeout response had been sent, calling res.send() resulted in the crash as the headers were already set to account for the timeout.

This was easily reproduced by setting a very short timeout and hitting the route with a decently-large image, the crash was reproduced every time.

Note
Rectangle 27 0

javascript Error: Can't set headers after they are sent to the client?


In my case this happened with React and postal.js when I didn't unsubscribe from a channel in the componentWillUnmount callback of my React component.

Note
Rectangle 27 0

javascript Error: Can't set headers after they are sent to the client?


auth.annonymousOnly = function(req, res, next) {
    if (req.user) return res.redirect('/');
    next();
};

I had this same issue and realised it was because I was calling res.redirect without a return statement, so the next function was also being called immediately afterwards:

Which should have been:

Note
Rectangle 27 0

javascript Error: Can't set headers after they are sent to the client?


30X redirect

A 30X redirect is an HTTP response code. w3.org/Protocols/rfc2616/rfc2616-sec10.html Codes 300-399 are different variations of redirection, with 302 and 301 being commonly used to send the client to an alternate URL. When you do response.redirect(...) in node, a 30X redirect header will be sent in the response.

I'm not sure exactly what's causing your error, but look at any callbacks as potential areas to investigate.

Lots of people hit this error. It's a confusing this with async processing. Most likely some of your code is setting headers in the first tick and then you are running an async callback in a future tick. In between, the response header gets sent, but then further headers (like a 30X redirect) try to add extra headers, but it's too late since the response header has already been transmitted.

One easy tip to simplify your code. Get rid of app.configure() and just call app.use directly in your top level scope.

See also the everyauth module, which does Facebook and a dozen or so other 3rd party authentication providers.

Note
Rectangle 27 0

javascript Error: Can't set headers after they are sent to the client?


// middleware that does not modify the response body
var doesNotModifyBody = function(request, response, next) {
  request.params = {
    a: "b"
  };
  // calls next because it hasn't modified the header
  next();
};

// middleware that modify the response body
var doesModifyBody = function(request, response, next) {
  response.setHeader("Content-Type", "text/html");
  response.write("<p>Hello World</p>");
  response.end();
  // doesn't call next()
};

app.use(doesNotModifyBody);
app.use(doesModifyBody);
render
res.setHeader('Content-Type', 'text/plain');
res.statusCode = 404;
res.setHeader('Content-Type', 'text/plain');
res.end('Cannot ' + req.method + ' ' + req.url);
response.headerSent
response.setHeader("Content-Type", "text/html");
response.write("<p>Hello World</p>");
var problemMiddleware = function(request, response, next) {
  response.setHeader("Content-Type", "text/html");
  response.write("<p>Hello World</p>");
  next();
};
  • there are no more items in the stack, and/or

+1 This is a great explanation, but what about the case when you use res.redirect()? I frequently run into this problem when the middleware is trying to redirect based on some condition. Should middleware not redirect, per your "Good Middleware" example?

I ran into this error as well for a while. I think (hope) I've wrapped my head around it, wanted to write it here for reference.

So, it throws an error. But the error it throws is just this basic response (from the connect http.js source code:

The problem is, if in one of the middleware items writes to the response body or headers (it looks like it's either/or for some reason), but doesn't call response.end() and you call next() then as the core Server.prototype.handle method completes, it's going to notice that:

The problematic middleware sets the response header without calling response.end() and calls next(), which confuses connect's server.

When you add middleware to connect or express (which is built on connect) using the app.use method, you're appending items to Server.prototype.stack in connect (At least with the current npm install connect, which looks quite different from the one github as of this post). When the server gets a request, it iterates over the stack, calling the (request, response, next) method.

You know I have this exact problem due to what you call a problematic middleware, however I need a case where I return response but would like to do further processing in a separate controller as part of the chain, how do I go about suppressing this error?

Note
Rectangle 27 0

javascript Error: Can't set headers after they are sent to the client?


var error = validateRequestDetails("create",queryReq);
    if (error)
        callback(error, null);
   else
    some code 
    callback(null, success);
var error = validateRequestDetails("create",queryReq);
    if (error)
        callback(error, null);
        return;
    else
       some code 
       callback(null, success);

I boiled my head over this issue and it has happened due to a careless mistake on handling the callbacks. non returned callbacks cause the response to be set twice.!

My program had a code which validate request and query the DB. after validating if error is there, I was calling back the index.js with the validation errors . And if validation passes it goes ahead and hit the db with success/failure.

So solution is simple, you need to 'return' the callback so that the method don't continue executing, once the error has occurred and hence set the response object once

Thanks! This turned out to be my problem too. Just did a ctrl+f and found a callback(...) without a return; after it which was eventually causing res.send(...) to be called twice.

What was happening is : Incase validation fails the callback get called and response get set. But not returned. So it still continues the method goes to db and hit success/failure . It calls the same callback again causing the response to be set twice now.

Note
Rectangle 27 0

javascript Error: Can't set headers after they are sent to the client?


res.send("something response");
console.log("jhgfjhgsdhgfsdf");
console.log("sdgsdfhdgfdhgsdf");
res.send("sopmething response");

If you want do anything, you should do it before sending the response.

This type of error you will get when you pass statements after sending a response.

Will result in the error you are seeing, because once the response has been sent, the following res.send will not be executed.

Note
Rectangle 27 0

javascript Error: Can't set headers after they are sent to the client?


app.use(function(req,res,next){
  var _send = res.send;
  var sent = false;
  res.send = function(data){
    if(sent) return;
    _send.bind(res)(data);
    sent = true;
};
  next();
});

Just leaned this. You can pass the responses through this function:

Note