Last updated: Mar 2, 2024
Reading time·3 min
The "Cannot set headers after they are sent to the client" error occurs when
the server in an express.js application sends more than one response for a
single request, e.g. calling res.json()
twice.
To solve the error, make sure to only send a single response for each request.
Here are some examples of how the error occurs.
app.get('/a', (req, res) => { res.send('Hello World!'); // ⛔️ Calling send method twice res.send('Hello World!'); }); // -------------------------------------------------- app.get('/b', (req, res) => { res.setHeader('Content-Type', 'application/json'); res.send('Hello World!'); // ⛔️ Setting headers after the response has been sent res.setHeader('Content-Type', 'text/html'); }); // -------------------------------------------------- app.get('/c', (req, res) => { // ⛔️ Using both send and redirect in a single response res.send('Hello World!!!'); res.redirect('/articles'); });
Here is the complete error message:
Error [ERR_HTTP_HEADERS_SENT]: Cannot set headers after they are sent to the client
The issue in the first example is that we used the res.send()
method twice in
a single route handler.
app.get('/a', (req, res) => { res.send('Hello World!'); // ⛔️ Calling send method twice res.send('Hello World!'); });
We sent two responses for a single HTTP request which caused the error.
if
statements and promises. A solution you can try is to return the response, e.g. return res.json()
.res.setHeader()
after sending a response to the clientThe second example tries to use the res.setHeader()
method after we have
already sent the response. This also causes the error.
app.get('/b', (req, res) => { res.setHeader('Content-Type', 'application/json'); res.send('Hello World!'); // ⛔️ Setting headers after the response has been sent ⛔️ res.setHeader('Content-Type', 'text/html'); });
res.send
and res.redirect
in a single responseThe third example uses the res.send()
and res.redirect()
methods and ends up
sending two responses to the client.
app.get('/c', (req, res) => { // ⛔️ Using both send and redirect in a single response res.send('Hello World!!!'); res.redirect('/articles'); });
next()
function twice in the same middlewarenext()
function multiple times in a single middleware.Make sure to only call a single function that sends a response for each request. These functions include:
res.redirect()
res.render()
res.send()
res.json()
Here's another common example of how the error occurs.
app.get('/a', (req, res) => { if (5 === 5) { // 👇️ this runs res.send('Hello'); } else if (10 === 50) { res.send('Bye'); } // 👇️ this also runs res.send('This also runs'); });
We didn't return from our if
and else if
statements, so the last line is
also run, which causes the error.
To avoid this, simply return the response.
app.get('/a', (req, res) => { if (5 === 5) { return res.send('Hello'); } else if (10 === 50) { return res.send('Bye'); } return res.send('This also runs'); });
return
statement.If you're working with async code, use async await because it makes your code more intuitive and readable.
This helps you avoid getting race conditions due to getting confused about which part of your code runs when.
app.get('/a', async (req, res) => { const status = 200; if (status === 200) { const result = await Promise.resolve('data'); return res.send(result); } else if (status === 404) { const err = await Promise.resolve('page not found'); return res.send(err); } return res.send('Server error'); });
When using async/await
, the code reads as if it were synchronous and is much
easier to follow.
This helps us to avoid returning a response before the promise has been resolved and then returning another response after.
I've also written an article on how to access the value of a Promise.
You can learn more about the related topics by checking out the following tutorials: