{"id":"IL-0583","org":"Uniform Next","date":"2025-07-24","docs":[],"title":{"en":"Service-to-service calls through Amazon VPC Lattice failed a few times a day with read ECONNRESET","ko":"VPC Lattice 를 거치는 ECS on Fargate 서비스 사이의 통신이 하루에 몇 번 ECONNRESET 으로 실패했다"},"domain":["networking","aws"],"impact":{"scope":"Some service-to-service requests through VPC Lattice failed, a few times a day","users":"unknown","region":"unknown"},"review":{"written_by":"session","reviewed_at":null,"reviewed_by":null},"lessons":{"en":"An idle timeout that is too long can also waste server resources, so it needs a suitable value. Managed services remove detailed settings but impose constraints, and some of their behaviour is not written explicitly in the documentation, so they need investigation and verification before use, even though a test that fully imitates production is often hard.","ko":"관리형 서비스를 쓰면 세세한 기술 설정을 직접 하지 않아도 되지만, 제약이 큰 경우가 많고 문서에 분명히 적히지 않은 사양도 있다. 쓰기 전에 충분히 조사하고 검증해야 하지만, 운영 환경을 그대로 재현해 검증하기는 어려운 경우가 많다. 그래서 글쓴이는 운영에서 난 문제를 조사하는 능력이 중요하다고 다시 느꼈다. 유휴 타임아웃은 너무 짧으면 연결을 맺는 오버헤드가 늘고, 너무 길면 서버 쪽 부하가 늘 수 있어 알맞은 값으로 정해야 한다."},"related":[],"sources":[{"url":"https://zenn.dev/uniformnext/articles/f8e4c7fc52b5f5","kind":"blog","archived":"https://web.archive.org/web/20250803202252/https://zenn.dev/uniformnext/articles/f8e4c7fc52b5f5"}],"summary":{"en":"Uniform Next uses Amazon VPC Lattice for service-to-service communication between applications on ECS on Fargate, and the client application reuses HTTP connections, keeping each one open until its own idle timeout expires. AWS Support confirmed that if a client sends a packet on the same TCP connection between 60 seconds, the VPC Lattice service's idle time, and 66 seconds, when the Lattice service sends a FIN packet, Lattice returns an RST packet by design.\n\nThe team considered two fixes: keep the application's idle timeout at 60 seconds or less, or send packets periodically so a connection never stays idle for 60 seconds. Because the Lattice idle time is fixed at 60 seconds and a shorter application idle timeout costs almost no performance, the team set the application's idle timeout to 60 seconds or less, and the error stopped.","ko":"Uniform Next 의 한 시스템은 서비스 사이의 통신에 VPC Lattice 를 쓴다. ECS on Fargate 에서 도는 Node.js 클라이언트가 다른 ECS 위의 타깃 애플리케이션으로 VPC Lattice Service 를 거쳐 통신하는데, 하루에 몇 번 Error: read ECONNRESET 으로 요청이 실패했다. 팀은 Datadog 의 오류 로그 감시에서 이를 발견했다.\n\nVPC Lattice 액세스 로그와 VPC 흐름 로그를 보니 클라이언트의 통신은 기록되어 있었지만 타깃 쪽 로그에는 없었다. tcpdump 로 보니 VPC Lattice Service 가 데이터 패킷 직후 RST 패킷을 보냈고, 그 연결은 약 60초 동안 쓰이지 않은 상태였다. 팀은 AWS 지원팀에 문의해 이 동작을 확인했다. 연결의 유휴 시간이 60초를 넘은 뒤 VPC Lattice Service 가 FIN 패킷을 보내는 66초가 되기 전에 클라이언트가 같은 TCP 연결로 패킷을 보내면, VPC Lattice Service 는 RST 패킷을 보내 연결을 강제로 끊는다. 이 유휴 시간 60초는 고정이다.\n\n해결 방법으로는 애플리케이션의 유휴 타임아웃을 60초 이하로 줄이거나, 유휴 시간이 60초를 넘지 않게 주기적으로 패킷을 보내는 두 가지가 있었다. 팀은 유휴 타임아웃을 줄여도 성능 저하는 거의 없다고 보고 애플리케이션의 유휴 타임아웃을 60초 이하로 줄였고, 그 뒤 같은 오류는 다시 나지 않았다."},"trigger":{"en":"The client sent a request on a reused TCP connection that had been idle for about 60 seconds.","ko":"클라이언트가 VPC Lattice Service 에 마지막으로 패킷을 보낸 지 60초에서 66초 사이에 그 TCP 연결을 다시 써서 요청을 보냈다."},"severity":"unknown","symptoms":["connection-resets"],"timeline":{"detected_after":null,"resolved_after":null},"date_kind":"published","detection":{"en":"Error log monitoring in Datadog showed Error: read ECONNRESET a few times a day.","ko":"Datadog 에서 오류 로그를 감시하던 중 Error: read ECONNRESET 이 하루에 몇 번씩 나는 것을 발견했다."},"components":["cloud-load-balancer"],"root_cause":"dns-network","remediation":[{"text":{"en":"Set the application's idle timeout to 60 seconds or less","ko":"애플리케이션의 유휴 타임아웃을 VPC Lattice Service 의 유휴 시간인 60초 이하로 줄였고, 그 뒤 같은 오류는 다시 나지 않았다."}}],"action_items":[],"contributing":["limit-unknown"],"recurrence_of":null,"symptoms_text":{"en":"While watching error logs in Datadog, Uniform Next engineers found that the error Error: read ECONNRESET occurred a few times a day. A Node.js application on ECS on Fargate calls another application on ECS through a VPC Lattice service, and a connection was being reset somewhere on that path.\n\nVPC Lattice access logs and VPC flow logs collected through CloudWatch showed the client's traffic recorded normally, but the failed requests did not appear in the target's VPC access logs or VPC flow logs. This pointed to the VPC Lattice service sending the RST packet.\n\ntcpdump inside the ECS task, run through ECS Exec, showed the Lattice endpoint answering a data packet from the task on port 80 with a packet flagged [R.]. The connection on the same ephemeral port, 41728, had been opened with a SYN about 60 seconds before that next packet was sent.","ko":"Datadog 에서 오류 로그를 감시하던 중 Error: read ECONNRESET 이 하루에 몇 번씩 나는 것을 발견했다. Node.js 애플리케이션이 VPC Lattice Service 를 거쳐 다른 서비스에 TCP 로 통신하다가 상대 쪽에서 연결이 강제로 끊긴 것이었다.\n\n구성은 ECS on Fargate 에서 도는 클라이언트 애플리케이션이 다른 ECS 위의 타깃 애플리케이션으로 VPC Lattice Service 를 거쳐 통신하는 형태였고, 이 경로 어딘가에서 연결이 리셋된 것으로 보였다.\n\nCloudWatch 로 VPC Lattice 액세스 로그와 VPC 흐름 로그를 모아 오류 시각을 확인했다. 클라이언트에서 보낸 통신은 정상으로 기록되어 있었지만, 타깃 쪽의 VPC 액세스 로그와 VPC 흐름 로그에는 그 통신이 없었다. 그래서 팀은 VPC Lattice Service 가 RST 패킷을 보냈다고 추정했다.\n\nECS Exec 로 컨테이너에 들어가 tcpdump 로 포트 80 의 패킷을 잡았다. 03:22:43.794429 에 ECS 태스크가 Flags [P.] 로 데이터를 보낸 직후 03:22:43.881892 에 VPC Lattice Service 쪽에서 Flags [R.] 패킷이 왔다. 같은 에페메랄 포트 41728 의 연결은 03:21:22.760166 에 Flags [S] 로 맺어졌고, 연결을 맺은 뒤 다음 패킷을 보내기까지 약 60초가 지나 있었다."},"updated_at":"2026-11-14T12:34:22.880384Z","url":"https://benchlet.com/incidentlib/app/cases/IL-0583","org_slug":"uniform-next"}