nginx 494: 요청 헤더가 너무 큼
494 Request Header Too Large는 nginx가 헤더(대개 비대한 쿠키)가 버퍼보다 커서 거부한 것. 클라이언트·서버를 3단계로 격리. 무료 즉시 진단으로 바로 확인.
내 도메인에 이 문제가 있는지 지금 확인
무료, 가입 불필요. 이 가이드가 다루는 항목을 바로 검사하고 조치 방법을 알려드립니다.
문제
nginx 접근 로그가 어떤 요청을 상태 494로 기록하고, 그 요청을 보낸 사람은 본문 Request Header Or Cookie Too Large가 담긴 400 Bad Request를 받습니다. 서버에는 아무 문제가 없습니다 — nginx가 크래시한 것도, 업스트림이 요청을 받은 것도 아니고, TLS도 멀쩡합니다. nginx는 실제 작업을 하기도 전에 요청을 거부했습니다. 요청의 헤더가 그것을 담아둘 버퍼보다 컸기 때문이죠. 열에 아홉은 쿠키가 조용히 살쪘다는 뜻입니다. 답할 가치가 있는 질문은 이게 모든 방문자에게 일어나는지, 아니면 특정 비대한 쿠키를 지닌 사람에게만 일어나는지입니다 — 그게 서버 설정을 아예 건드릴지 말지를 결정하니까요.
증상
- 클라이언트는 본문
Request Header Or Cookie Too Large가 담긴400 Bad Request를, nginx 접근 로그는 상태494를 봅니다. - 일부 사용자만 겪습니다 — 대개 사이트에 오래 머물러 쿠키가 쌓인 쪽 — 반면 새 브라우저나 시크릿 창은 잘 열립니다.
- 그 사이트의 쿠키를 지우면 즉시 사라졌다가, 앱이 쿠키를 다시 만들면서 며칠에 걸쳐 되살아나기도 합니다.
- 헤더가 큰 엔드포인트에서 더 잘 납니다: SSO 뒤의 페이지,
Authorization에 큰 JWT를 싣는 앱, 또는 자체 헤더를 주입하는 프록시 뒤의 무엇이든.
이 에러가 실제로 뜻하는 것
494는 nginx의 비표준 내부 상태 코드 중 하나로, 소스에서 495(클라이언트 인증서 검증 실패)·496(클라이언트가 인증서 미제시)·497(HTTPS 포트로 온 평문 HTTP) 바로 옆에 정의돼 있습니다. 내부적으로는 NGX_HTTP_REQUEST_HEADER_TOO_LARGE입니다. 494는 등록된 HTTP 상태가 아니라서 nginx는 클라이언트에 그것을 절대 보내지 않고, 400 Bad Request를 반환하며 로그에 494를 남깁니다.
핵심은 정책이 아니라 버퍼입니다. nginx는 요청 라인과 처음 헤더를 client_header_buffer_size가 정한 버퍼에 읽는데, 기본값이 1KB입니다. 헤더가 안 들어가면 large_client_header_buffers에서 버퍼를 할당하고, 기본값은 8KB짜리 4개입니다. 사람들이 놓치는 규칙이 있습니다: 한 줄짜리 헤더 — 이름 하나와 그 값 — 는 버퍼 하나 안에 들어가야 합니다. 그래서 8KB 버퍼 4개는 Cookie 헤더 하나에 32KB 예산을 주는 게 아니라, 각각 8KB에 들어가는 여러 헤더를 담을 자리를 줄 뿐입니다. 버퍼 하나보다 큰 Cookie 줄 하나면 버퍼 개수와 무관하게 494가 뜹니다. 그래서 해법이 어떤 때는 “버퍼를 키워라”이고 어떤 때는 “거대한 쿠키를 그만 보내라”인데, 이 둘을 가려내는 게 일의 전부입니다.
가장 흔한 원인 3가지
- 너무 커진 쿠키 - 압도적으로 흔합니다. 세션 데이터·추적 픽셀·A/B 테스트 배정·기능 플래그가 시간이 지나며 쿠키에 쌓이고, 브라우저는 그 도메인으로 가는 모든 요청에 전부 실어 보냅니다. 결국
Cookie헤더 하나가 버퍼 하나를 넘고, 쿠키를 지울 때까지 그 브라우저의 모든 요청이 494를 받습니다. 사이트 전체가 아니라 한 사용자 브라우저만 그렇다면 거의 이것입니다. - 큰 토큰이나 주입된 헤더 -
Authorization의 두꺼운 JWT, 긴Referer, 또는 nginx 앞단의 프록시·SSO 게이트웨이·WAF가 붙인 헤더. 맥락을 덧붙이는 홉마다(X-Forwarded-*, 인증 클레임, 트레이스 헤더) 헤더 블록이 커져서, 브라우저에서는 한계 아래이던 요청이 nginx에 닿을 즈음엔 넘어 있습니다. - 헤더가 무거운 앱인데 버퍼가 기본값 - 1KB / 8KB 기본값은 평범한 사이트엔 충분하고, 정당하게 큰 인증 헤더를 싣는 사이트엔 너무 작습니다. 쿠키 무거운 사용자뿐 아니라 모든 사용자가 494를 겪는다면, 서버 버퍼가 실제 서빙하는 트래픽에 비해 작은 것입니다.
DechoNet으로 진단
- HTTP 점검은 같은 URL을 당신 네트워크 밖에서, 쿠키 없는 최소한의 헤더로 요청합니다. 실제 브라우저는
494/400을 받는데 DechoNet은 정상200을 받으면, 서버는 멀쩡하고 비대한 헤더는 클라이언트에서 오는 것입니다 — 그 사이트 쿠키를 지우면 문제도 함께 사라집니다. DechoNet도400 Request Header Or Cookie Too Large를 받으면, 서버가 작은 요청조차 거부하는 것이라 버퍼가 너무 낮거나 앞단 프록시가 헤더를 주입하는 쪽을 가리킵니다. 그 한 번의 점검이 설정 파일을 건드리기 전에 어느 쪽을 고쳐야 하는지 알려줍니다.
해결 체크리스트
- 재현하고 범위를 좁히세요. 일반 브라우저(실패)와 쿠키 없는 시크릿 창(성공)으로 URL을 엽니다. 시크릿이 되면 클라이언트측, 시크릿도 실패하면 서버측 문제입니다.
- 클라이언트 문제라면 그 사이트 쿠키를 지우세요(또는 겪는 사용자에게 지우게 하세요). 그다음 무엇이 쿠키를 부풀리는지 찾으세요 — 쿠키에 계속 덧붙이는 앱, 추적 스크립트, 서버측에 있어야 할 세션 데이터 — 다시 자라지 않도록.
- 서버 문제라면
http블록에서 버퍼를 키우세요:client_header_buffer_size 4k;,large_client_header_buffers 4 16k;. 모든 server 블록이 상속하도록http레벨에 두고 nginx를 리로드합니다. 한 줄 규칙을 기억하세요: 헤더 하나가 버퍼 하나를 넘으면 개수가 아니라 크기(그16k)를 키워야 합니다. - 앞단에 프록시·로드밸런서·SSO 게이트웨이가 있다면 무슨 헤더를 붙이는지 확인하세요. 중간 장비가 인증·포워딩 헤더를 덧붙이는 바람에 브라우저에서는 작던 요청이 nginx에서 커질 수 있습니다. 주입하는 것을 줄이거나, 실제 헤더 총량에 맞춰 nginx 버퍼를 잡으세요.
- 무제한 버퍼로 덮지 마세요. 아주 큰 헤더 버퍼는 메모리·서비스 거부(DoS) 지뢰입니다. 모든 연결에 64KB 헤더 공간을 주기보다 쿠키나 주입된 헤더를 고치세요.
에스컬레이션 시점
- 쿠키를 지우면 고쳐지는데 며칠 뒤 되돌아온다면, 애플리케이션이 비대한 쿠키를 다시 만드는 것입니다. 그건 nginx 설정이 아니라 앱 변경 — 데이터를 서버측으로 옮기거나 쿠키 덧붙이기를 멈추는 일 — 입니다.
- 프록시나 CDN을 통할 때만 나고 오리진 직접 요청은 깨끗하다면, 중간 장비가 헤더를 부풀리는 것입니다. 직접 대 프록시 경유 증거와 함께 그 홉 담당자에게 넘기세요.
- 인증하는 순간 모든 사용자가 494를 겪는다면, 인증 헤더(JWT나 SSO 쿠키)가 정당하게 버퍼 하나보다 큰 것입니다. 토큰을 줄이거나 그에 맞게
large_client_header_buffers를 잡으세요 — 클라이언트에서 “지울” 것은 없습니다.
관련 도구
관련 가이드
가이드 공유