Troubleshooting

[Node.js/Express] ERR_HTTP_HEADERS_SENT 에러 원인과 해결 방법

KnovyLab 2026. 9. 29. 14:24

ERR_HTTP_HEADERS_SENT 에러 코드 스크린샷

Node.js + Express로 작업하다가 아래 에러가 발생했다.

Error [ERR_HTTP_HEADERS_SENT]:
Cannot set headers after they are sent to the client

처음에는 header 설정에 문제가 있나 싶었는데, 확인해보니 이미 응답을 보낸 상태에서 다시 응답을 보내려고 해서 발생한 에러였다.

원인

Express에서 res.send(), res.json(), res.redirect() 같은 메서드를 호출하면 클라이언트에게 응답이 전달된다.

문제는 한 요청에서 이미 응답을 보낸 뒤, 이후 코드에서 res.json()이나 res.send() 같은 응답 메서드를 다시 호출하는 경우다.

예를 들면 아래와 같다.

app.get('/user', (req, res) => {
  if (!req.query.id) {
    res.status(400).json({
      message: 'id가 필요합니다.',
    });
  }

  res.json({
    message: '정상 처리되었습니다.',
  });
});

id가 없는 경우 먼저 400 응답을 보내지만, 여기서 함수 실행 자체가 끝나는 것은 아니다.

때문에 아래에 있는 res.json()까지 실행되면서 하나의 요청에 두 번 응답하게 되고,

ERR_HTTP_HEADERS_SENT

에러가 발생한다.

해결

내 경우에는 조건문 안에서 응답을 보낸 뒤 return을 하지 않은 것이 원인이었다.

app.get('/user', (req, res) => {
  if (!req.query.id) {
    return res.status(400).json({
      message: 'id가 필요합니다.',
    });
  }

  return res.json({
    message: '정상 처리되었습니다.',
  });
});

여기서 한 가지 헷갈릴 수 있는 부분이 있다.

실제로 응답을 보내는 것은 return이 아니라 res.json()이다.

return은 res.json() 이후 현재 함수의 실행을 종료해서, 아래쪽 코드가 계속 실행되는 것을 막는 역할을 한다.

즉,

return res.status(400).json(...);

처럼 작성하면 응답을 보낸 뒤 해당 핸들러가 바로 종료되기 때문에 아래에서 다시 응답하는 상황을 막을 수 있다.

자주 발생하는 경우

1. res를 두 번 호출한 경우

res.send('hello');
res.send('world');

이미 첫 번째 res.send()에서 응답이 전송됐기 때문에 두 번째 응답을 보낼 수 없다.

2. 조건문에서 return이 빠진 경우

if (!user) {
  res.status(404).json({
    message: '사용자를 찾을 수 없습니다.',
  });
}

res.json(user);

user가 없으면 404 응답을 보내지만, 이후 코드가 계속 실행되면서 res.json(user)도 호출된다.

아래처럼 응답을 보낸 뒤 함수를 종료하면 된다.

if (!user) {
  return res.status(404).json({
    message: '사용자를 찾을 수 없습니다.',
  });
}

return res.json(user);

3. 비동기 처리 중 여러 경로에서 응답하는 경우

async/await를 사용하는 코드에서도 비슷하게 발생할 수 있다.

try {
  const user = await getUser();

  if (!user) {
    return res.status(404).json({
      message: '사용자를 찾을 수 없습니다.',
    });
  }

  return res.json(user);
} catch (error) {
  return res.status(500).json({
    message: '서버 오류가 발생했습니다.',
  });
}

조건문이나 예외 처리 등 여러 분기에서 응답을 보내고 있다면, 특정 경우에 res가 중복 호출되고 있지 않은지 확인해보는 게 좋다.

res.headersSent로 확인하기

어디에서 응답이 먼저 나가고 있는지 찾기 어려운 경우에는 res.headersSent도 확인해볼 수 있다.

console.log(res.headersSent);

응답을 보내기 전에는 일반적으로

false

이고,

res.json({
  message: 'ok',
});

console.log(res.headersSent);

응답을 보낸 이후에는

true

가 된다.

코드가 복잡해서 응답이 중복되는 위치를 찾기 어렵다면 중간중간 res.headersSent를 찍어보는 것도 도움이 된다.

정리

ERR_HTTP_HEADERS_SENT가 발생하면 먼저 하나의 요청에서 응답을 두 번 보내고 있지 않은지 확인하면 된다.

특히 아래 부분을 먼저 보면 빠르게 찾을 수 있다.

  • res.send(), res.json(), res.redirect()가 중복 호출되고 있는지
  • 조건문에서 응답을 보낸 뒤 return이 빠져 있지 않은지
  • async/await, try/catch 등 여러 분기에서 각각 응답하고 있지 않은지

내 경우에는 단순하게 조건문 안의 응답 코드에서 return이 빠져 있었고, 이를 추가한 뒤 해결됐다.

참고

 

 

최초 작성: 2021년 12월 9일

'Troubleshooting' 카테고리의 다른 글

npm install 설치 npm ERR! code ERESOLVE 해결  (0) 2026.09.29