How to fix Error: Cannot set headers after they are sent to the client in Node.js

Node.jsINTERMEDIATEHIGHUpdated Dec 9, 2025· 147 views

This error occurs when your Express or Node.js application attempts to modify HTTP response headers after the response body has already been sent to the client. This typically happens when multiple responses are sent per request or when headers are set after res.send(), res.json(), or similar methods.

Quick fix

Fixes ERR_HTTP_HEADERS_SENT

// WRONG
app.get('/user', (req, res) => {
  res.json({ id: 1, name: 'John' });
  res.setHeader('X-Custom', 'value'); // Error: headers already sent
});

// CORRECT
app.get('/user', (req, res) => {
  res.json({ id: 1, name: 'John' });
  return; // Prevents further execution
});

// OR more idiomatically
app.get('/user', (req, res) => {
  return res.json({ id: 1, name: 'John' });
});
  1. Add return statements after sending responses
  2. Ensure only one response is sent per request
  3. Set headers before sending the response body
  4. Handle async operations with proper error handling
node.js — error
// WRONG
app.get('/user', (req, res) => {
res.json({ id: 1, name: 'John' });
res.setHeader('X-Custom', 'value'); // Error: headers already sent
});
// CORRECT
app.get('/user', (req, res) => {
res.json({ id: 1, name: 'John' });
return; // Prevents further execution
});
// OR more idiomatically
app.get('/user', (req, res) => {
return res.json({ id: 1, name: 'John' });
});
Error: Cannot set headers after they are sent to the client

What this error means

In Node.js HTTP servers, response headers must be sent to the client before the response body. Once the headers have been sent, you cannot modify them. This error occurs when code tries to set or modify headers (using res.setHeader(), res.writeHead(), etc.) after the response has already started being sent to the client via res.send(), res.json(), res.write(), or other response-sending methods. The HTTP protocol requires headers to be transmitted first, followed by the response body. Once this transmission begins, the headers are locked and cannot be changed.

Typical symptoms

  • Express or Node.js application crashes with ERR_HTTP_HEADERS_SENT error
  • Error occurs intermittently or only in certain request scenarios
  • Multiple responses seem to be generated for a single request
  • Error happens with asynchronous operations (callbacks, promises)
  • Application returns partial responses before crashing

Common causes

  1. Sending multiple responses per request (calling res.send(), res.json(), or res.write() more than once)
  2. Setting headers after a response has been sent using res.setHeader() or res.writeHead()
  3. Missing return statements after sending a response, causing code to continue executing
  4. Improper error handling that attempts to send an error response after a successful response was already sent
  5. Async callback or promise handler attempting to send headers after an earlier response was already sent
  6. Middleware functions incorrectly ordered, with header-setting middleware placed after response-sending middleware
  7. Conditional logic that doesn't properly exit when sending a response (if/else if chains without returns)

How to fix "Error: Cannot set headers after they are sent to the client"

1Add return statements after sending responses

Use return when calling res.send(), res.json(), or other response methods to prevent further code execution:

javascript
// WRONG
app.get('/user', (req, res) => {
  res.json({ id: 1, name: 'John' });
  res.setHeader('X-Custom', 'value'); // Error: headers already sent
});

// CORRECT
app.get('/user', (req, res) => {
  res.json({ id: 1, name: 'John' });
  return; // Prevents further execution
});

// OR more idiomatically
app.get('/user', (req, res) => {
  return res.json({ id: 1, name: 'John' });
});
2Ensure only one response is sent per request

Restructure conditional logic to guarantee only one response path is executed:

javascript
// WRONG - both paths execute
app.get('/data', (req, res) => {
  if (req.query.format === 'json') {
    res.json({ data: 'value' });
  }
  if (!req.query.format) {
    res.send('No format specified');
  }
});

// CORRECT - only one path executes
app.get('/data', (req, res) => {
  if (req.query.format === 'json') {
    return res.json({ data: 'value' });
  }
  if (!req.query.format) {
    return res.send('No format specified');
  }
  res.status(400).send('Invalid format');
});
3Set headers before sending the response body

Always call res.setHeader() or res.writeHead() before res.send(), res.json(), or res.write():

javascript
// WRONG
app.get('/data', (req, res) => {
  res.send('Hello World');
  res.setHeader('Content-Type', 'text/plain'); // Too late!
});

// CORRECT
app.get('/data', (req, res) => {
  res.setHeader('Content-Type', 'text/plain');
  res.send('Hello World');
});

// Also correct - headers implicitly set by json()
app.get('/api/data', (req, res) => {
  res.json({ message: 'Hello' }); // Sets Content-Type: application/json
});
4Handle async operations with proper error handling

When using callbacks or promises, ensure responses are only sent once and in the correct order:

javascript
// WRONG - response could be sent twice
app.get('/user/:id', (req, res) => {
  User.findById(req.params.id, (err, user) => {
    if (err) {
      res.status(500).send('Error finding user');
    }
    res.json(user); // Might execute even if error was sent
  });
});

// CORRECT - early return prevents double responses
app.get('/user/:id', (req, res) => {
  User.findById(req.params.id, (err, user) => {
    if (err) {
      return res.status(500).send('Error finding user');
    }
    return res.json(user);
  });
});

// With async/await (cleaner)
app.get('/user/:id', async (req, res) => {
  try {
    const user = await User.findById(req.params.id);
    return res.json(user);
  } catch (err) {
    return res.status(500).send('Error finding user');
  }
});
5Use res.headersSent to guard header modifications

Check the res.headersSent flag before attempting to modify headers in complex scenarios:

javascript
app.get('/data', (req, res) => {
  // ... some processing ...

  if (!res.headersSent) {
    res.setHeader('X-Custom', 'value');
  }

  // Send response
  res.json({ data: 'value' });
});

// In middleware
app.use((req, res, next) => {
  // Only add custom header if response hasn't been sent yet
  if (!res.headersSent) {
    res.setHeader('X-Request-ID', generateId());
  }
  next();
});
6Fix middleware ordering

Ensure middleware that modifies headers is placed before middleware/routes that send responses:

javascript
// WRONG - header middleware comes after route that sends response
app.get('/data', (req, res) => {
  res.send('Data');
});

app.use((req, res, next) => {
  res.setHeader('X-Custom', 'value');
  next();
});

// CORRECT - header middleware before routes
app.use((req, res, next) => {
  res.setHeader('X-Custom', 'value');
  next();
});

app.get('/data', (req, res) => {
  res.send('Data');
});

Advanced notes

The HTTP specification defines that headers must be sent before the response body. In Node.js, once res.writeHead() is called (which happens implicitly in res.send(), res.json(), etc.), the headers are locked. Some frameworks track this with res.headersSent (boolean flag).

When piping streams, be careful with error handling - a pipe to the response can trigger multiple end events. Always check res.headersSent or use proper error event handlers on streams.

In Express error handlers, always send a response before calling next() to avoid double responses. Express error handlers have a different signature (4 parameters: err, req, res, next) - they should be registered last in your app.

Frequently asked questions

What does "ERR_HTTP_HEADERS_SENT" mean?
js HTTP servers, response headers must be sent to the client before the response body. Once the headers have been sent, you cannot modify them. write(), or other response-sending methods.
How do I fix "ERR_HTTP_HEADERS_SENT"?
This error occurs when your Express or Node.js application attempts to modify HTTP response headers after the response body has already been sent to the client. This typically happens when multiple responses are sent per request or when headers are set after res.send(), res.json(), or similar methods.
What causes "ERR_HTTP_HEADERS_SENT"?
Sending multiple responses per request (calling res.send(), res.json(), or res.write() more than once) Setting headers after a response has been sent using res.setHeader() or res.writeHead() Missing return statements after sending a response, causing code to continue executing
Is the "ERR_HTTP_HEADERS_SENT" error serious?
Yes. This is a high-severity error that usually blocks work until it is fixed, but the steps above resolve it.

Official resources & further reading