ERR_HTTP2_PROTOCOL_ERROR 오류 원인과 해결 방법

핵심 요약

ERR_HTTP2_PROTOCOL_ERROR(Chromium 오류 -337)는 페이지를 실어 나르는 HTTP/2 스트림이 실패했다는 뜻입니다. 서버, 프록시 또는 CDN이 도중에 스트림을 재설정했거나(Chrome은 이런 재설정을 모두 -337로 보고합니다), Chrome이 HTTP/2 규칙을 어긴 헤더를 거부한 경우입니다. 방문자라면 새로고침, 시크릿 창, 해당 사이트의 쿠키 삭제, 백신의 HTTPS 검사 일시 중지로 해결될 때도 있지만, 대부분은 사이트 쪽에서만 고칠 수 있습니다. 사이트 운영자라면 흔한 원인은 서버나 프록시가 끝까지 보내지 못한 응답(디스크 가득 참, 쓸 수 없는 임시 폴더, 앱 충돌), 본문과 맞지 않는 Content-Length, Transfer-Encoding 같은 금지된 헤더입니다. curl --http2 -v로 재현해 보세요.

지금 확인하기

ERR_HTTP2_PROTOCOL_ERROR가 표시된 Chrome 오류 페이지와 HTTP/2 프로토콜 오류를 해결하는 점검 항목
ERR_HTTP2_PROTOCOL_ERROR가 표시된 Chrome 오류 페이지와 HTTP/2 프로토콜 오류를 해결하는 점검 항목
읽기 시작
  1. ERR_HTTP2_PROTOCOL_ERROR란?
  2. HTTP/2가 잘못된 형식으로 간주하는 것
  3. ERR_HTTP2_PROTOCOL_ERROR의 원인
  4. 해결 방법 1: 강력 새로고침 후 시크릿 창에서 열기
  5. 해결 방법 2: 해당 사이트의 쿠키와 캐시 파일 삭제하기
  6. 해결 방법 3: 백신 HTTPS 검사와 확장 프로그램 일시 중지
  7. 해결 방법 4: Chrome 업데이트 및 다른 브라우저 확인
  8. 해결 방법 5: HTTP/2 없이 페이지 테스트하기
  9. 웹사이트 운영자용: HTTP/2 프로토콜 오류 해결하기
  10. 1. curl로 재현하기
  11. 2. 스트림 도중 잘린 응답 확인하기
  12. 3. Content-Length와 금지된 헤더 수정하기
  13. ERR_HTTP2_PROTOCOL_ERROR와 비슷한 오류 비교
  14. 자주 묻는 질문

ERR_HTTP2_PROTOCOL_ERROR란?

ERR_HTTP2_PROTOCOL_ERROR는 페이지를 실어 나르는 HTTP/2 스트림이 실패했다는 뜻의 Chrome·Edge 오류입니다. 서버가 스트림이 끝나기 전에 재설정했거나, 브라우저가 거부하는 헤더를 보냈다는 의미입니다. Chromium 내부에서는 네트워크 오류 -337이며, "There is an HTTP/2 protocol error"로 설명되어 있습니다(net_error_list.h). Chrome에는 이 오류 전용 페이지가 없어 일반 오류 페이지가 표시됩니다. '사이트에 연결할 수 없음'이라는 제목과 함께 '…의 웹페이지가 일시적으로 다운되었거나 새 웹 주소로 완전히 이동했을 수 있습니다.'라는 문구가 나오고, 그 아래에 ERR_HTTP2_PROTOCOL_ERROR가 표시됩니다. Edge도 자체 오류 화면에 같은 코드를 표시합니다.

HTTP/2는 요즘 대부분의 HTTPS 사이트가 쓰는 더 빠른 HTTP입니다. 각 요청은 하나의 연결 안에서 독립된 스트림으로 오가며, 양쪽 모두 재설정으로 스트림을 취소할 수 있습니다. Chrome은 서버에서 온 재설정을 서버의 이유와 상관없이 프로토콜 오류로 보고합니다. 또한 헤더가 HTTP/2 규칙을 어길 때(Transfer-Encoding 헤더, 헤더 이름의 대문자, 누락된 상태 등)에는 Chrome이 직접 스트림을 취소합니다.

개발자는 DevTools 콘솔에서 net::ERR_HTTP2_PROTOCOL_ERROR 200 (OK) 형태로 자주 보게 됩니다. 이 조합은 강력한 단서입니다. 헤더는 올바르고 서버가 200으로 응답했지만, 본문이 도착하는 도중에 스트림이 실패했다는 뜻입니다.

페이지가 실제로 보내는 헤더 확인하기

HTTP/2가 잘못된 형식으로 간주하는 것

HTTP/2 표준(RFC 9113)은 응답을 잘못된 형식으로 만드는 실수를 나열합니다. 실제 오류 대부분이 이 문제들 때문이며, 각각이 브라우저에 어떻게 전달되는지는 다음과 같습니다.

규칙이를 어기는 경우
Content-Length는 본문 크기와 같아야 함서버나 플러그인이 선언한 크기와 실제로 보낸 크기가 다릅니다. 앞단의 프록시, CDN 또는 서버가 스트림을 재설정합니다
응답은 깔끔하게 끝나야 함서버, 프록시 또는 앱이 응답을 끝내지 못하고(디스크 가득 참, 충돌, 시간 초과) 스트림을 재설정합니다. nginx는 이미 시작한 응답을 완료하지 못할 때 이렇게 합니다
연결 전용 헤더 금지HTTP/2 응답의 Transfer-Encoding(Chrome이 거부). Connection, Keep-Alive, Proxy-Connection, Upgrade도 금지이며, curl 같은 엄격한 클라이언트는 이를 거부합니다
필드 이름은 소문자여야 함대문자가 들어간 헤더 이름이 HTTP/2로 그대로 전달됩니다
유효한 헤더 값헤더 값 안의 줄바꿈이나 그 밖의 금지된 문자
유효한 :status 의사 헤더누락되었거나 읽을 수 없는 상태 코드

ERR_HTTP2_PROTOCOL_ERROR의 원인

대부분은 서버 쪽에서 발생하지만, 내 컴퓨터의 몇 가지 요소가 들어오는 응답을 손상시킬 수도 있습니다:

  • 서버 쪽: 서버나 프록시가 끝내지 못하는 응답(디스크 공간이 부족하거나 임시 파일을 쓰지 못하는 프록시, 스트리밍 중 충돌하는 앱, 시간 초과), 앞단 프록시가 포기하게 만드는 잘못된 Content-Length 값, 금지되거나 유효하지 않은 헤더, 오래된 서버나 CDN 설정의 HTTP/2 지원 버그.
  • 사용자 쪽: HTTPS를 검사하며 트래픽을 다시 쓰는 백신이나 방화벽 소프트웨어, 요청이나 응답을 수정하는 브라우저 확장 프로그램, 서버가 제대로 처리하지 못하는 요청(예: 지나치게 큰 쿠키), 그리고 드물게 오래된 Chrome 버전.

해결 방법 1: 강력 새로고침 후 시크릿 창에서 열기

Ctrl + Shift + R(Mac: Cmd + Shift + R)을 눌러 캐시 없이 새로고침하세요. 한 번 잘렸던 응답이 다음 시도에서는 정상적으로 도착할 수 있습니다.

그다음 시크릿 창(Ctrl + Shift + N, Mac Cmd + Shift + N)에서 페이지를 열어 보세요. 시크릿 창에는 쿠키도, 평소 프로필의 캐시도 없고 확장 프로그램도 기본적으로 꺼져 있습니다. 여기서 페이지가 열린다면 해결 방법 2나 해결 방법 3으로 평소 창에서도 해결됩니다.

해결 방법 2: 해당 사이트의 쿠키와 캐시 파일 삭제하기

사이트의 쿠키와 캐시 파일을 지우면 Chrome이 보내는 요청이 달라져(쿠키가 줄고, 다시 확인할 캐시 사본이 없어져) 서버 버그를 피할 수 있습니다. 주소창 왼쪽의 사이트 정보 보기를 클릭 → 쿠키 및 사이트 데이터 → 기기 내 사이트 데이터 관리 → 삭제 후 새로고침하세요. 더 넓게 정리하려면 Ctrl + Shift + Delete를 누르고 지난 7일 동안의 캐시된 이미지 및 파일을 지우세요.

해결 방법 3: 백신 HTTPS 검사와 확장 프로그램 일시 중지

HTTPS를 복호화해 검사하는 보안 소프트웨어는 모든 HTTP/2 연결의 중간에 자리 잡고 있습니다. 이 소프트웨어의 HTTP/2 처리에 버그가 있거나 오래되었다면 스트림을 망가뜨리거나 Chrome이 거부하는 헤더를 그대로 넘길 수 있습니다. HTTPS 검사 기능만 끄고(Avast/AVG: 웹 실드 → Enable HTTPS scanning, ESET: SSL/TLS 프로토콜 필터링, Kaspersky: 암호화된 연결 검사) 새로고침하세요. 그것으로 해결된다면 백신을 업데이트하고 해당 사이트를 예외로 추가하세요.

다음으로 chrome://extensions에서 모든 확장 프로그램을 끄고 새로고침한 뒤, 하나씩 다시 켜 보세요. 광고 차단기, 개인 정보 보호 도구, 헤더를 수정하는 모든 것이 흔한 원인입니다.

해결 방법 4: Chrome 업데이트 및 다른 브라우저 확인

chrome://settings/help를 열어 대기 중인 업데이트를 설치하고 브라우저를 다시 시작하세요. 그다음 같은 페이지를 Firefox나 Safari에서, 그리고 다른 기기나 네트워크에서도 열어 보세요. 어디서든 실패한다면 사이트 자체가 고장 난 것이며 고칠 수 있는 사람은 운영자뿐입니다(백신의 HTTPS 검사는 한 컴퓨터의 모든 브라우저에 영향을 주므로 두 번째 기기가 진짜 시험입니다). Chrome이나 Edge에서만 실패한다면 사이트가 Chrome이 거부하는 헤더를 보내고 있을 가능성이 높지만, 해결 방법 2와 3을 다시 시도해 볼 가치는 있습니다.

해결 방법 5: HTTP/2 없이 페이지 테스트하기

Chrome은 HTTP/2(와 HTTP/3)를 끈 채로 시작할 수 있으며, 이를 통해 HTTP/2가 관련되어 있는지 확인할 수 있습니다. 터미널에서 두 번째로 별도의 Chrome을 시작하세요. 추가 프로필 폴더를 지정하면 평소 Chrome이 열려 있어도 새 인스턴스가 됩니다.

bash
# Windows (Command Prompt)
"C:\Program Files\Google\Chrome\Application\chrome.exe" --user-data-dir="%TEMP%\h2test" --disable-http2 --disable-quic

# macOS (Terminal)
open -na "Google Chrome" --args --user-data-dir=/tmp/h2test --disable-http2 --disable-quic

그 창에서 페이지가 열린다면 HTTP/2 응답이 문제이므로 운영자가 고쳐야 합니다. 이제 ERR_CONTENT_LENGTH_MISMATCH나 ERR_INCOMPLETE_CHUNKED_ENCODING으로 실패한다면, 프로토콜과 상관없이 서버가 응답을 도중에 끊고 있는 것입니다. 끝나면 그 창을 닫으세요. 평소 Chrome에는 영향이 없습니다.

웹사이트 운영자용: HTTP/2 프로토콜 오류 해결하기

서로 다른 네트워크와 브라우저를 쓰는 방문자들이 이 오류를 보고한다면 문제는 내 서버 스택에 있습니다. 다음 세 가지 점검으로 거의 모든 원인을 찾을 수 있습니다.

1. curl로 재현하기

bash
# HTTP/2: watch the end of the output
curl -sv --http2 https://example.com/broken-page -o /dev/null
# A stream the server gave up on ends with something like:
# HTTP/2 stream 1 was not closed cleanly: INTERNAL_ERROR (err 2)
# (curl 8.19+: HTTP/2 stream 1 reset by server (error 0x2 INTERNAL_ERROR);
#  "reset by curl" means curl rejected the response itself)

# Same URL over HTTP/1.1 for comparison
curl -sv --http1.1 https://example.com/broken-page -o /dev/null

HTTP/1.1은 되는데 HTTP/2만 실패한다면 HTTP/2가 관련되어 있는 것입니다. "Reset by server"는 서버나 프록시가 응답 도중에 포기했다는 뜻입니다. curl은 Chrome과 똑같은 것을 검사하지 않으므로(Chrome이 통과시키는 Content-Length 불일치와 연결 헤더를 curl은 거부합니다) 증거가 아니라 강한 단서로 보세요. HTTP 헤더 검사기에서는 앱이 설정한 헤더를 네트워크 바깥에서 본 모습으로 확인할 수 있습니다.

2. 스트림 도중 잘린 응답 확인하기

서버 쪽에서 가장 흔한 원인은 시작은 했지만(상태 200, 헤더 전송 완료) 끝내지 못하는 응답입니다. nginx는 앱에서 온 큰 응답을 임시 파일에 버퍼링하는데, 디스크가 가득 찼거나 nginx가 임시 폴더에 쓰지 못하면 스트림을 재설정하고 브라우저는 프로토콜 오류를 보고합니다. 다음을 확인하세요.

bash
df -h                                   # is any disk full?
sudo grep -E "No space left|Permission denied" /var/log/nginx/error.log | tail
ls -ld /var/lib/nginx/proxy /var/lib/nginx/fastcgi   # Debian/Ubuntu packages
ls -ld /var/cache/nginx/proxy_temp /var/cache/nginx/fastcgi_temp   # nginx.org packages
# the temp folders must be writable by the nginx worker user

앱 자체도 확인하세요. 큰 페이지나 다운로드를 스트리밍하는 도중 크래시하거나, 타임아웃되거나, 메모리 제한에 걸리는 PHP나 Node 프로세스도 같은 결과를 냅니다. 오류 발생 시각 전후의 앱 로그에 대개 흔적이 남아 있습니다.

3. Content-Length와 금지된 헤더 수정하기

  • Content-Length: 서버가 계산하게 두세요. 플러그인, 미들웨어 또는 웹 서버가 출력을 함께 압축하거나 수정한다면 앱 코드에서 직접 설정하지 마세요. 선언한 길이가 실제로 보낸 바이트 수와 더 이상 맞지 않게 됩니다. PHP 코드에서 길이를 설정하는데 플러그인이나 PHP 설정도 출력을 압축하는 경우가 WordPress 사이트에서 이런 일이 생기는 한 가지 방식입니다.
  • Transfer-Encoding: HTTP/2 응답에서는 절대 보내지 마세요. Chrome은 이 헤더를 보는 순간 스트림을 재설정합니다. RFC 9113은 Connection, Keep-Alive, Proxy-Connection, Upgrade도 금지합니다. Chrome은 이들을 무시하지만 curl 같은 엄격한 클라이언트는 거부하며, nginx는 프록시된 응답에서 대부분을 대신 제거해 줍니다.
  • 헤더 값: 어떤 헤더에도 줄바꿈이나 제어 문자가 없는지 확인하세요. Content-Disposition의 파일 이름처럼 사용자 입력이 헤더에 그대로 들어가서 생기는 경우가 많습니다.
  • 앞단의 CDN: Cloudflare나 다른 CDN을 쓴다면 오리진을 직접 테스트해(curl의 --resolve 또는 hosts 항목 사용) 오류가 오리진에서 오는지 CDN에서 오는지 가려내세요.

ERR_HTTP2_PROTOCOL_ERROR와 비슷한 오류 비교

오류코드무슨 일이 일어났나
ERR_HTTP2_PROTOCOL_ERROR-337HTTP/2 응답이 프로토콜 규칙을 어김
ERR_QUIC_PROTOCOL_ERROR-356HTTP/3(QUIC)에서 발생한 같은 종류의 실패
ERR_SSL_PROTOCOL_ERROR-107HTTP/2가 시작되기 전에 HTTPS(TLS) 핸드셰이크가 실패함
ERR_CONNECTION_CLOSED-100페이지가 도착하기 전에 연결이 닫힘
ERR_EMPTY_RESPONSE-324서버가 아무것도 보내지 않음

자세한 가이드: ERR_QUIC_PROTOCOL_ERROR, ERR_SSL_PROTOCOL_ERROR, ERR_CONNECTION_CLOSED, ERR_EMPTY_RESPONSE. 사이트의 인증서와 HTTPS 설정을 외부에서 확인하려면 SSL 인증서 확인 도구를 사용하세요.

내 사이트가 실제로 보내는 헤더 확인하기

DNS Robot의 HTTP 헤더 검사기는 저희 서버에서 HTTP/1.1로 아무 URL이나 가져와 상태 코드와 앱이 설정한 모든 응답 헤더(Content-Length, Content-Encoding, Content-Disposition)를 보여 줍니다. curl --http2 결과와 비교해 보세요.

출처

  1. net_error_list.h (HTTP2_PROTOCOL_ERROR -337), Chromium
  2. RFC 9113: HTTP/2, 잘못된 형식의 메시지, IETF
  3. HTTP/2: ERR_HTTP2_PROTOCOL_ERROR, Cloudflare

자주 묻는 질문

ERR_HTTP2_PROTOCOL_ERROR는 무슨 뜻인가요?

페이지를 실어 나르는 HTTP/2 스트림이 실패했다는 뜻입니다. 대개 서버, 프록시 또는 CDN이 응답이 끝나기 전에 스트림을 재설정하고 Chrome이 이를 프로토콜 오류로 보고합니다. 때로는 Transfer-Encoding처럼 HTTP/2가 금지하는 헤더를 Chrome이 거부한 경우도 있습니다. Chromium에서는 네트워크 오류 -337입니다.

ERR_HTTP2_PROTOCOL_ERROR는 내 문제인가요, 웹사이트 문제인가요?

대개 웹사이트 쪽 문제입니다. 백신의 HTTPS 검사, 브라우저 확장 프로그램, 지나치게 큰 쿠키가 원인일 수도 있으니 먼저 강력 새로고침, 시크릿 창, HTTPS 검사 일시 중지를 시도해 보세요. 모든 브라우저와 모든 네트워크에서 실패한다면 고칠 수 있는 사람은 사이트 운영자뿐입니다.

net::ERR_HTTP2_PROTOCOL_ERROR 200은 무슨 뜻인가요?

헤더는 올바르고 서버가 200으로 응답했지만, 본문이 도착하는 도중에 스트림이 실패했다는 뜻입니다. 서버, 프록시 또는 CDN이 중간에 재설정했습니다. 흔한 원인은 디스크 공간이 부족하거나 임시 파일을 쓰지 못한 프록시, 응답 도중 충돌한 앱, 본문과 맞지 않는 Content-Length입니다.

Chrome에서 ERR_HTTP2_PROTOCOL_ERROR를 해결하려면 어떻게 하나요?

Ctrl + Shift + R로 강력 새로고침하고, 시크릿 모드를 시도하고, 해당 사이트의 쿠키와 캐시 파일을 지우고, 백신의 HTTPS 검사를 일시 중지하고, 확장 프로그램을 끄고, Chrome을 업데이트하세요. HTTP/2가 관련되어 있는지 확인하려면 --user-data-dir, --disable-http2, --disable-quic을 붙인 별도의 Chrome을 시작해 페이지가 열리는지 보세요.

Chrome에서 HTTP/2를 끌 수 있나요?

설정 페이지에서는 불가능합니다. 테스트할 때는 --disable-http2와 --disable-quic을 붙인 별도의 Chrome을 시작하세요(--user-data-dir도 함께 지정하지 않으면 이미 실행 중인 Chrome이 플래그를 무시합니다). 그 실행에만 적용됩니다. HTTP/2는 사이트를 더 빠르게 만들어 주므로 이는 진단용일 뿐 장기적인 해결책이 아닙니다.

내 nginx 사이트에서 ERR_HTTP2_PROTOCOL_ERROR가 발생하는 이유는 무엇인가요?

디스크가 가득 찼는지, nginx가 프록시나 FastCGI 임시 폴더에 쓸 수 있는지(오류 로그에서 "No space left on device" 또는 "Permission denied"를 찾으세요), 앱이 응답 도중 충돌하는지, 앱이 Transfer-Encoding 헤더나 잘못된 Content-Length를 보내는지 확인하세요. curl --http2 -v로 재현해 보세요.

Cloudflare 때문에 ERR_HTTP2_PROTOCOL_ERROR가 발생할 수 있나요?

대개 원인은 오리진입니다. Cloudflare 문서는 잘못된 형식의 오리진 헤더와 압축 문제(Content-Length가 갱신되지 않은 gzip 본문 또는 손상된 gzip)를 흔한 원인으로 꼽으며, 트래픽이 Cloudflare를 거칠 때만 나타날 수도 있습니다. Cloudflare를 거치지 않고 오리진을 직접 테스트하세요.

ERR_HTTP2_PROTOCOL_ERROR와 ERR_QUIC_PROTOCOL_ERROR의 차이는 무엇인가요?

서로 다른 프로토콜에서 일어나는 같은 종류의 실패입니다. ERR_HTTP2_PROTOCOL_ERROR는 HTTP/2(TCP 기반)에서, ERR_QUIC_PROTOCOL_ERROR는 HTTP/3(QUIC 기반)에서 발생합니다. 후자는 QUIC을 방해하는 방화벽이나 백신 소프트웨어도 흔한 원인입니다.

캐시를 지우면 ERR_HTTP2_PROTOCOL_ERROR가 해결되나요?

가끔은 됩니다. 사이트의 쿠키와 캐시 파일을 지우면 Chrome이 보내는 요청이 달라져 서버 버그를 피할 수 있으니 시도해 볼 만합니다. 서버가 계속 스트림을 재설정하거나 잘못된 헤더를 보낸다면 사이트가 수정될 때까지 오류가 다시 나타납니다.

작성자 소개

Shaik Vahid

DNS Robot 창립자. Vahid는 수년간 웹 호스팅 지원 업무를 하며 고객의 도메인, DNS 레코드, SSL 인증서, 이메일 전송 문제를 해결했습니다. DNS Robot의 도구를 만들고, 사람들이 실제로 겪는 오류를 바탕으로 이 가이드를 씁니다.

HTTP 헤더 검사

HTTP 응답 헤더 분석 및 보안 헤더 등급 평가