문제 요약
로컬 개발서버를 자체 서명 인증서를 사용해 HTTPS로 띄우고 크롬으로 접근시, 일부 리소스가 net::ERR_TOO_MANY_RETRIES 콘솔 에러를 표시하며 로드가 되지 않음
자체 서명 인증서: 인증 기관(CA)에서 발급하지 않은 공개 키 인증서. 해당 인증서를 사용해서 개발 서버 실행해 접근 시 아래와 같은 경고 화면을 볼 수 있다. (크롬)
크롬에서는 고급 버튼을 클릭해 경고를 무시하고 접근이 가능하다. #allow-insecure-localhost 플래그를 사용하여 localhost에서 이 경고를 자동으로 우회할 수도 있다.
상황
개발하는 사이트의 세션은 쿠키로 관리하고 있었다. http://localhost는 개발 목적으로 HTTPS처럼 작동하여 그대로 사용하고 있었으나, 최근에 쿠키에 domain을 설정하게 되면서 localhost를 더 이상 사용할 수 없었다. 쿠키에 설정된 도메인으로 로컬 개발서버에 접근해야 로그인이 가능하게 되었다.
작업하고 있는 레포지토리에서는 공용으로 쓰고 있던 자체 서명 인증서가 있어서 그것을 vite config server.https에 설정해 주었었다.
export default defineConfig({
...
server: {
https: {
cert: fs.readFileSync('../../cert/mysite.pem'),
key: fs.readFileSync('../../cert/mysite-key.pem'),
}
...
}
})
그렇게 개발 서버를 실행한 후 크롬으로 접근해 확인했더니 일부 레거시 css 파일이 로드되지 않아 사이트 ui가 깨져 보였다. 콘솔에서 확인해 보니 net::ERR_TOO_MANY_RETRIES 에러 메시지가 확인되었다.
문제 원인
검색해보니 동일한 문제에 대해 보고하는 오래된 글들이 확인되었다.
동일한 증상을 보고한 글
- https://issues.chromium.org/issues/40655776
- https://stackoverflow.com/questions/58086327/google-chrome-neterr-too-many-retries
근본 원인에 대해 논의하는 글
요약 (챗GPT 사용)
- 증상:
- 자체 서명 인증서를 사용하는 HTTPS 서버에서 리소스가 간헐적으로 로드되지 않음
- 원인 개요:
- 인증서 예외(클릭스루) 시도 중 무한 재시도
- 크롬은 "인증서 오류"가 발생하면 상위 레이어(브라우저 UI 등)에 “인증서 오류 무시 여부”를 묻는다.이를 “사용자가 수락”하면, 연결 재시도가 이루어지는데 이때 소켓 풀과 인증서 설정(allow_bad_certs) 파라미터가 서로 맞지 않게 되면 요청이 계속 재시도되는 문제가 발생.
- 소켓 풀의 연결 제한
- 동일 호스트에 대해 소켓 풀은 기본적으로 6개의 소켓 연결을 시도할 수 있음.페이지 리소스가 많을 경우(150+ 리소스 로드) 여러 연결이 동시에 인증서 오류로 인해 무한 재시도 => 소켓 풀이 포화 상태가 되고, 결국 일부 요청은 끝내 실패하게 됨(또는 무한 반복).
- 캐싱 충돌 및 로드 플래그 차이
- 새로고침(F5) 시에는 MAYBE_USER_GESTURE라는 플래그가 켜져서, 자바스크립트가 정상적으로 로드되는 반면, 일반 로드시에는 이 플래그 없이 인증서 에러로 인해 일부 로드가 중단되기도 함.
- 인증서 예외(클릭스루) 시도 중 무한 재시도
- 이에 대해 일부 패치가 이루어졌으나 여전히 문제 발생함
해결 방법
- 자체 서명 인증서가 아닌, 로컬 인증 기관을 설치해서 발급한 인증서를 쓰면 된다.
- 로컬 인증 기관 설치를 위해 mkcert를 설치한다. 안내가 잘나와있는 아래 문서의 링크를 참고하면 좋다.
- https://web.dev/articles/how-to-use-local-https?hl=ko#mkcert
- vite의 경우 server.https에 mkcert를 통해 발급한 인증서를 설정해주어도 되지만, 아래 플러그인들을 설치해 config에 설정해주면 좀 더 편리하다. 인증서 발급 + 인증서 파일 경로 설정의 공수를 줄일 수 있다.