ECONNRESET은 포트가 비어서 거절된 줄이 아니라 한 번 붙었던 소켓을 상대가 갑자기 닫아서 요청이 중간에 끊긴 줄입니다. 원인 코드, 연결 재사용, 토스·카카오 웹훅은 성공 응답을 먼저 보냅니다. Node.js, Next.js, 한국 1인 개발자 기준. 2026년 9월 Node.js 에러·MDN Fetch 문서.
붙었던 소켓을 상대가 강제로 닫아서 납니다. 거절은 그 주소와 포트에 수신자가 없을 때이고, 리셋은 핸드셰이크 이후입니다. Node.js 문서는 이 코드를 시스템 에러로 두고, 소켓이 상대의 RST 패킷을 받았을 때 던진다고 적습니다.
그래서 터미널에 서버가 떠 있어도 이 줄이 납니다. 프로세스는 살아 있는데 그 요청을 처리하던 연결만 끊긴 겁니다. 카카오 로그인 콜백이 한 번은 되고 다음 번에 떨어질 때도 같은 그림입니다. 포트가 막혀 서버가 시작도 못 하는 줄은 EADDRINUSE이고, 시작 전에 거절되는 줄은 ECONNREFUSED입니다.
시간 초과와도 갈립니다. 한도까지 기다리다 죽은 줄은 ETIMEDOUT입니다. 리셋은 기다리기 전에 상대가 연결을 잘라 버린 쪽에 가깝습니다. 호스트 이름을 IP로 못 바꾼 줄은 ENOTFOUND라서, 메시지 앞 코드부터 읽으면 칸이 갈립니다.
먼저 읽을 것 | 에러 객체에 code가 ECONNRESET인지, 그 아래 cause에 다른 코드가 있는지 보세요. 언디치 fetch는 겉에 TypeError만 남기고 진짜 코드는 안쪽에 있습니다.
거절은 시작 전, 리셋은 붙은 뒤에 상대가 연결을 잘라 버린 줄이다
어느 쪽이 소켓을 끊었는지 가리기
클라이언트 로그와 서버 로그를 같은 시각으로 맞춥니다. 표로 먼저 나눕니다.
칸
증상
먼저 볼 곳
상대 프로세스 종료
요청 도중 서버 창이 사라짐
서버 로그의 크래시, OOM, 미처리 예외
프록시 유휴 끊기
긴 작업만 중간에 떨어짐
nginx proxy_read_timeout, 로드밸런서 idle
연결 재사용
첫 요청은 되고 다음만 리셋
Keep-Alive, 언디치 에이전트, Connection: close
본문 길이 불일치
업로드·웹훅만 끊김
Content-Length와 실제 바이트, 청크 종료
TLS 핸드셰이크 중단
HTTPS만 리셋, HTTP는 통과
인증서 체인, SNI, 중간자 검사
한국에서 카카오·토스 웹훅을 받는 1인 넥스트라면 네 번째 칸을 자주 만납니다. 상대가 보낸 본문 길이와 서버가 읽은 길이가 다르면 프록시가 연결을 잘라 RST를 남깁니다. 다섯 번째 칸은 인증서 글과 자리가 겹치니, 코드가 리셋이면 여기 표를 먼저 보고 HTTPS만 실패하면 인증서 칸으로 넘기세요.
언디치 fetch에서 원인 코드 꺼내기
try {
const res = await fetch(url, { signal: AbortSignal.timeout(15_000) })
if (!res.ok) throw new Error('HTTP ' + res.status)
} catch (err) {
const code = err.cause?.code || err.code
console.error('fetch 실패', code, err.message)
// ECONNRESET / ECONNREFUSED / ETIMEDOUT / ENOTFOUND 가 여기서 갈린다
}
연결 재사용과 프록시에서 자주 나는 이유
서버가 유휴 연결을 먼저 닫으면 클라이언트가 그 소켓을 재사용하다 리셋됩니다. 노드 기본 HTTP 에이전트와 언디치는 연결을 풀에 남겨 둡니다. 앞단 엔진엑스나 클라우드 로드밸런서가 유휴 60초에 끊는데 클라이언트는 아직 살아 있다고 믿으면, 다음 요청이 RST를 받습니다.
고치는 법은 유휴 시간을 맞추는 것입니다. 클라이언트 keep-alive를 프록시보다 짧게 두거나, 문제 나는 경로만 Connection: close로 한 번 쓰고 버립니다. 긴 작업은 응답을 먼저 보내고 뒤를 돌리는 편이 안전합니다. 버셀 함수 한도에 걸리는 줄은 FUNCTION_INVOCATION_TIMEOUT이고, 그 한도 전에 소켓만 잘리면 여기 리셋입니다.
로컬 엔진엑스 없이 넥스트만 띄운 창에서는 잘 안 보입니다. 프리뷰 도메인 앞에 CDN이 붙는 순간 유휴 규칙이 달라집니다. 카카오 콜백 URL이 프리뷰와 프로덕션이 다르면, 한쪽만 리셋이 나는 이유도 여기 있습니다.