문제

서버가 431 Request Header Fields Too Large로 요청을 거부합니다. 응답에는 어느 헤더 또는 전체 헤더 크기가 한도를 넘었는지에 대한 짧은 안내가 종종 포함됩니다.

증상

  • 페이지가 431 Request Header Fields Too Large(또는 이 코드 이전 서버에선 400 Bad Request)를 반환합니다.
  • 일부 사용자에게만 실패하거나, 사이트를 한동안 이용한 뒤에만 실패합니다.
  • 도메인 쿠키를 지우거나 시크릿 창으로 열면 다시 됩니다.
  • 큰 Authorization·Cookie·Referer 헤더가 실린 특정 요청만 실패하고 나머지는 성공합니다.

이 오류의 실제 의미

431은 429 Too Many Requests를 준 것과 같은 문서인 RFC 6585(2012)에서 정의됐습니다. 말 그대로 요청의 헤더 섹션이 서버가 처리하기엔 너무 컸다는 뜻입니다. 명세는 두 가지를 허용합니다 — 모든 헤더 필드의 총합이 한도를 넘었거나, 단일 필드 하나가 너무 컸거나 — 서버는 어느 쪽인지 응답 본문에 표시할 수 있습니다.

핵심은 그 크기가 어디서 오느냐입니다. 헤더 비대는 거의 언제나 Cookie 헤더입니다. 브라우저는 도메인에 설정된 모든 쿠키를 하나의 헤더로 이어 붙여 매 요청마다 보냅니다. 쿠키를 심는 분석 스크립트, A/B 테스트 도구, 채팅 위젯, 마케팅 픽셀 하나하나가 여기에 더해집니다. 몇 달이면 한 도메인에 킬로바이트 단위 쿠키가 쌓이고, 어느 날 한 요청이 서버 임계값을 넘습니다. 또 다른 단골은 큰 Authorization 헤더입니다 — 클레임이 많은 두툼한 JWT, 또는 스코프가 늘며 커진 토큰.

서버 한도는 사람들이 생각하는 것보다 낮습니다. Node.js는 기본 전체 헤더 크기를 16 KB로 제한하며 — 버전 11.6.0과 13.13.0 사이에는 8 KB였습니다. 헤더 기반 서비스 거부 취약점 CVE-2018-12121에 대응해 조인 값입니다. nginx는 large_client_header_buffers로 8 KB 버퍼 4개가 기본입니다. 이 한도는 일부러 존재합니다. 무제한 헤더는 메모리 고갈 공격이며, 그래서 “그냥 한도를 하늘까지 올려”가 잘못된 첫 수인 것입니다.

주요 원인 3가지

  1. 누적된 쿠키 - 도메인에 몇 달간 쌓인 분석·마케팅·서드파티 쿠키로 Cookie 헤더가 한도를 넘었습니다. 가장 흔한 원인이며, 사용자별로 다르고 “쿠키 지우면 고쳐지는” 패턴을 설명합니다.
  2. 비대한 단일 헤더 하나 - Authorization의 큰 JWT, 아주 긴 Referer, 인코딩된 상태를 실은 커스텀 헤더. 여기선 총합은 괜찮아도 한 필드가 필드별 한도를 넘습니다.
  3. 앱에 비해 너무 낮게 설정된 서버 한도 - 애플리케이션이 정당하게 큰 헤더를 요구하는데(큰 SAML/JWT 토큰을 쓰는 SSO가 흔함) 웹 서버/런타임 기본값이 앱이 필요로 하는 것보다 작습니다.

DechoNet으로 진단

  • HTTP Check로 서버가 반환하는 정확한 상태와 응답 헤더를 보고, 상위 어딘가의 다른 실패가 아니라 431(또는 그 대역인 400)임을 확인합니다.
  • DNS Lookup로 사용자마다 결과가 다를 때 의도한 호스트에 접속하는 게 맞는지, 오래된 엔드포인트나 잘못된 환경이 아닌지 확인합니다.

해결 체크리스트

  • 시크릿/프라이빗 창에서 재현합니다. 거기서 되면 원인은 클라이언트 쪽 헤더 비대 — 거의 확실히 쿠키입니다.
  • 브라우저 DevTools(Network 탭)에서 실패한 요청의 헤더를 살펴보고 가장 큰 것을 찾습니다 — 보통 Cookie, 때로 Authorization.
  • 쿠키가 원인이면 정리합니다: 오래됐거나 서드파티인 쿠키 제거, 필요한 경로로 쿠키 스코프 지정, 도메인에 쿠키를 심는 스크립트 점검.
  • 헤더 하나가 원인이면(큰 토큰) 줄입니다 — JWT 클레임을 다듬거나, 부피 큰 상태를 헤더에서 빼 서버 측 세션 참조로 옮깁니다.
  • 설계상 헤더가 정당하게 클 때만 서버 한도를 의도적으로 올립니다: Node --max-http-header-size, nginx large_client_header_buffers, Apache LimitRequestFieldSize / LimitRequestFields. 무한이 아니라 앱이 필요로 하는 값으로.
  • HTTP Check를 재실행해 요청이 이제 성공하는지 확인합니다.

에스컬레이션 시점

  • 비대한 헤더가 직접 제어할 수 없는 SAML/JWT 토큰이면 신원/SSO 팀에 에스컬레이션하세요 — 해결책이 앱이 아니라 신원 공급자에서 클레임을 줄이는 것일 수 있습니다.
  • 앞단의 CDN/리버스 프록시가 자체의 (더 낮은) 헤더 한도를 강제하면, 오리진은 받아줬을 요청에도 엣지에서 431이 나올 수 있습니다. 오리진만이 아니라 엣지의 헤더 크기 설정도 확인하세요.

내 도메인에서 바로 확인

무료, 가입 불필요. 이 가이드가 다루는 항목을 바로 검사하고 조치 방법을 알려드립니다.