Node.js HTTP: ERR_HTTP_HEADERS_SENT

Jul 1, 2021 12:03:25 PM | Node.js HTTP: ERR_HTTP_HEADERS_SENT

What does a Node.js HTTP error ERR_HTTP_HEADERS_SENT mean? How do you fix it? Learn more about this error in this article.

Introduction 

If you see the Node.js HTTP error, ERR_HTTP_HEADERS_SENT, there’s likely an issue with the response within your code. Your server may be trying several times to reach a client and failing because it can’t find the header. 

The fix for this tends to be fairly simple. Throughout this article, we’ll go over where this error resides in the Node.js hierarchy, what it is, and how to fix it.

The Node.js HTTP Technical Rundown 

The ERR_HTTP_HEADERS_SENT is a runtime error that lies with the Node.js Error.code hierarchy

  • Error
    • Error.code
      • ERR_HTTP_HEADERS_SENT

The nice thing about errors within the “Error.code” is that their names typically reflect what type of error you are receiving. So, in this case, the error will have something to do with HTTP headers.  

What is the ERR_HTTP_HEADERS_SENT Error?

According to the Node.js docs, an ERR_HTTP_HEADERS_SENT is “an attempt made to add more headers after the headers [have] already been sent.” 

Let’s break this down a bit. 

If you’re receiving this error, this means that a part of your code is attempting to send a header after the body has already been written to the HTTP response. It’s similar to when you send a formal letter. The letter can only be sent if you include an address. Without an address, your letter isn’t going anywhere, which means that nobody will be able to read its content. The headers and body on an HTTP responsive work the same way. When sending headers with your HTTP response, you must write the headers before sending the body, otherwise you won't be able to send the content of the body.

Now that you know a bit about this particular error, it’s time to learn how to fix it. 

How to Fix an ERR_HTTP_HEADERS_SENT 

As developers, you have choices as to how you want to code. You might code using only Node.js, or you might be using the Express.js framework. Because both are valid ways to code using Node.js, we’ll go over this error for both Node.js and Express.js.  

Node.js Example

Here’s an example of what your code might look like if you’re only using Node.js: 

const http = require('http');
server = http.createServer(function (req, res) {
res.write('Hello, World!');
res.setHeader('X-Foo', 'bar');
res.setHeader('Content-Type', 'text/plain');
res.end();
}).listen(8080);

And, as soon as you run it and issue this request: curl -i localhost:8080, the server will die with this output:

_http_outgoing.js:561
throw new ERR_HTTP_HEADERS_SENT('set');
^
Error [ERR_HTTP_HEADERS_SENT]: Cannot set headers after they are sent to the client
at ServerResponse.setHeader (_http_outgoding.js:561:11)
at Server.<anonymous> (/Users/ssb/src/node-tmp/server.js:5:7)
at Server.emit (events.js:376:20)
at parserOnIncoming (_http_server.js:896:12)
at HTTPParser.parserOnHeadersComplete (_http_common.js:126:17) {
code: 'ERR_HTTP_HEADERS_SENT'
}

Yikes! So, what did we do wrong here?  

As we discussed before, an HTTP response to a client has to have its headers written before the body of the response.

 res.write('Hello, World!');
res.setHeader('X-Foo', 'bar');
res.setHeader('Content-Type', 'text/plain');

The res.setHeader is called after the res.write, inevitably leading to an ERR_HTTP_HEADERS_SENT error. 

Here’s what the code should look like

 res.setHeader('X-Foo', 'bar');
res.setHeader('Content-Type', 'text/plain');
res.write('Hello, World!');

If you’re receiving this error, take a moment and check your code. Look for instances where the body procedes the header.

Express.js Example 

As a developer working with Node.js code, you might be using the Express.js framework. Code that produces the ERR_HTTP_HEADERS_SENT error will look a bit different compared to Node.js code.

Here’s an example of Express.js code that will produce this error:

const express = require('express')
const app = express()
const port = 8080
app.get('/', (req, res) => {
res.send('Hello World!')
res.setHeader('X-Foo', 'bar')
})
app.listen(port, () => {
console.log(`Example app listening at http://localhost:${port}`)
})

Once you run the HTTP server and curl the endpoint with curl -i localhost:8080, your terminal will spit out the following error: 

Error [ERR_HTTP_HEADERS_SENT]: Cannot set headers after they are sent to the client
at ServerResponse.setHeader (_http_outgoing.js:561:11)
at /Users/ssb/src/node-tmp/index.js:7:7

The code above produces this error because of this block:

app.get('/', (req, res) => {
res.send('Hello World!')
res.setHeader('X-Foo', 'bar')
})

The body of the code is sent before the header. As you know, you can’t send the body before the header. Fix this by rewriting your code the following way:

app.get('/', (req, res) => {
res.setHeader('X-Foo', 'bar')
res.send('Hello World!')
})

And that’s it! It’s a simple fix for a frustrating error.

How Do I Find This Node.js HTTP Error? 

Without an error monitoring software or debugger, the only way to find this error is to go through your logs. With hundreds, if not thousands, of lines of code to sift through, this can prove to be a lengthy endeavor just to find one error. That’s where Airbrake Error and Performance Monitoring comes in. With Airbrake Node.js and Express.js Error Monitoring, you can skip the logs and go straight to the code that’s producing the ERR_HTTP_HEADERS_SENT error. 

Don’t have Airbrake? Sign up for a risk-free, 14-day Airbrake trial today for unlimited errors, unlimited users, unlimited projects, and so much more.

Written By: Alexandra Lindenmuth