505 HTTP Version Not Supported: 버전이 문제가 아니다
505 HTTP Version Not Supported는 서버가 HTTP 메이저 버전을 거부한 것입니다. 잘못된 요청 라인과 프록시 재작성을 구분하세요. 무료 HTTP 진단으로 바로 확인.
내 도메인에 이 문제가 있는지 지금 확인
무료, 가입 불필요. 이 가이드가 다루는 항목을 바로 검사하고 조치 방법을 알려드립니다.
문제
505 HTTP Version Not Supported를 받으면 이름이 거의 모두를 엉뚱한 길로 보냅니다: “내 HTTP 버전이 너무 낡았으니 뭔가를 업그레이드해야겠다.” 열에 아홉은 그 해석이 정확히 거꾸로입니다. RFC 9110 §15.6.6은 505를 서버가 요청 메시지에 사용된 HTTP의 메이저 버전을 지원하지 않거나 지원을 거부할 때의 응답으로 정의합니다. 핵심 단어는 메이저입니다.
그 단어가 사람들이 의심하는 대부분을 걸러냅니다. HTTP/1.0과 HTTP/1.1은 같은 메이저 버전 — 1 — 을 공유하므로, 1.1을 말하는 서버는 1.0 요청에 505를 내지 않습니다. 그냥 답합니다. HTTP/2와 HTTP/3은 애초에 요청 라인에서 고르는 게 아닙니다: HTTP/2는 TLS 위에서 ALPN으로 협상되고, HTTP/3은 Alt-Svc로 광고됩니다. 그래서 브라우저는 정상적인 버전 협상으로는 사실상 505에 이를 수 없습니다. 실제로 505를 본다면, 무언가가 서버가 받아들일 수 없는 버전 필드를 담은 요청 라인을 보낸 것이고 — 그 무언가는 대개 당신이 노려보고 있는 브라우저가 아니라 깨진 요청이거나 중간의 어느 홉입니다.
증상
- 상태줄이
505 HTTP Version Not Supported로 뜨고, 본문은 애플리케이션 오류 형식이 아니라 일반 서버·프록시 오류 페이지입니다. - 특정 클라이언트 — 스크립트, SDK, 구형 기기, 스캐너 — 에서 재현되고, 평범한 브라우저는 같은 URL을 잘 엽니다.
- 앱 앞에 뭔가 새로 얹은 직후 나타납니다: 프록시, 로드밸런서, API 게이트웨이, CDN.
- 서버 로그를 볼 수 있다면, 서버가 실제로 받은 요청 라인이 보이고 — 그 안의 버전 토큰이 잘못돼 있습니다.
주요 원인 3가지
- 잘못된 요청 라인 - 가장 흔한 진짜 원인이고, 버전이 낡은 것과는 아무 상관이 없습니다. 타깃에 인코딩 안 된 공백을 넣거나, 요청 라인을
\r\n이 아니라 맨\n으로 끝내거나, 비표준 버전 토큰을 쓰는 클라이언트는 서버가HTTP-version필드를 잘못 파싱하게 만듭니다. 엄격한 서버는 505로, 관대한 서버는 400으로 답하거나 그냥 넘어갑니다. 그래서 같은 URL이 브라우저에선 되고 손으로 만든 요청에선 505인 것입니다. 예컨대 nginx는 의도적으로 어떤HTTP/1.x든 받아들입니다 — 그러니 nginx 프런트엔드에서 나온 505는 대개 버전 문자열이 알아볼 수 있는1.x조차 아니었다는 뜻입니다. - 더 좁은 버전을 말하는 중간 노드 - 교활한 경우입니다. 당신 오리진은 멀쩡하거든요. 업스트림으로 HTTP/1.0을 말하도록 설정된 리버스 프록시·로드밸런서·CDN — 또는 버전 라인을 재작성하는 노드 — 가 오리진을 대신해 요청을 거부하고 505를 반환할 수 있습니다. 요청은 앱에 도착조차 못 합니다. 단서는 그 전형적인 갈림입니다: 오리진을 직접 치면 되고 공개 호스트명으로는 실패한다는 것.
- 지원 안 되는 메이저 버전에 고정된 클라이언트 - 정직한 경우입니다. 서버가 정말로 서빙하지 않는 무언가에 하드와이어된 레거시·임베디드 클라이언트 — HTTP/0.9, 또는 서버가 비활성화한 메이저 버전을 주장하는 요청 라인 — 는 솔직한 505를 받습니다. 여기선 수정이 클라이언트 쪽입니다: HTTP/1.1로 올리세요.
DechoNet으로 진단
- HTTP 점검은 깨끗하고 잘 짜인 요청으로 URL을 가져와 원시 상태와 응답 헤더를 보여줍니다. DechoNet은 200을 받는데 당신 클라이언트는 505라면, 서버가 올바른 요청 라인은 잘 서빙함을 증명한 것입니다 — 문제는 서버 자체가 아니라 보내는 쪽이나 클라이언트 요청이 거치는 어느 홉입니다.
- DNS 점검은 호스트명이 프록시/CDN을 가리키는지 오리진을 곧장 가리키는지 보여줍니다. 엣지 네트워크를 가리키면, 자기만의 HTTP 버전 처리를 가진 계층을 찾은 것이고 — 오리진 단독으로는 되는데 공개 URL이 505일 때의 첫 번째 용의자입니다.
해결 체크리스트
- 클라이언트가 보내는 정확한 요청 라인을 캡처하세요(디버그 도구로 프록시하거나 서버 액세스 로그를 읽으세요). 버전 토큰이 문자 그대로
HTTP/1.1이고 줄이\r\n으로 끝나며 타깃에 흩어진 공백이 없는지 확인합니다. - 검증된 클라이언트로 재현하세요:
curl -v https://yourdomain.com/path. curl은 200인데 당신 클라이언트가 505면, 버그는 클라이언트가 요청을 조립하는 방식에 있습니다 — 타깃을 퍼센트 인코딩하고 줄 종결자를 고치세요. - 프록시·CDN을 우회해 오리진을 직접 테스트하세요(올바른
Host헤더로 오리진 IP). 오리진은 응답하고 공개 URL은 505 → 중간 노드가 버전을 거부하는 것입니다. 그 홉의 HTTP 버전 설정을 고치세요(예: 프록시가 업스트림으로 HTTP/1.1을 말하게). - 클라이언트가 옛 메이저 버전에 고정돼 있으면 HTTP/1.1로 올리세요. 서버가 HTTP/0.9를 받아들이게 만들어 덮지 마세요 — 원치 않는 요청 스머글링 표면이 다시 열립니다.
- 이걸 426과 혼동하지 마세요. 서버가 정말로 당신을 TLS나 HTTP/2로 올리고 싶으면 426과
Upgrade헤더로 그렇게 말합니다.Upgrade헤더 없는 맨 505는 새 프로토콜로의 안내가 아니라 거부입니다.
에스컬레이션 시점
- 요청 라인이 명백히 올바르고, 앞에 프록시도 없는데 오리진이 여전히 505면, 전체 원시 요청·응답 바이트를 캡처하세요. HTTP/1.1을 명백히 지원하는 소프트웨어에서 나온 505는 버전 필드를 재작성하는 특정 미들박스나 WAF를 가리킵니다 — 버그가 아니라 그 박스를 찾으세요.
- 매니지드 플랫폼이나 CDN이 당신이 모양을 바꿀 수 없는 트래픽(옛 파트너 연동, 고정된 기기)에 505를 반환하면, 해결은 그 플랫폼의 요청 파싱·프로토콜 설정이거나 그쪽 지원 요청이지, 오리진에서 패치할 수 있는 게 아닙니다.
- 오류를 잠재우려고 서버가 잘못됐거나 오래된 요청 라인을 받아들이도록 느슨하게 만들고 싶다면, 멈추세요. 지저분한 요청 프레이밍을 관대히 넘기는 서버는 요청 스머글링에 더 취약한 서버입니다. 대신 쓰레기를 보내는 클라이언트나 홉을 고치세요.
관련 도구
관련 가이드
가이드 공유